Author | Message | Time |
---|---|---|
CupHead | I'm looking to have the user select a process and then, based on that, reroute the calls that that program makes through my program, and then back to the original program. So far I've heard about replacing the DLL that the target program uses with my own, but this doesn't seem to be a viable solution as my program needs to be able to attach to just about any other program. There was also code injection, which I'm sure will have to be used at some point, although I'm not sure exactly how. Lastly, there was overwriting the IAT of the target program, which seems like a good idea, but once again, no idea of how to implement something like that. | December 15, 2003, 5:36 PM |
Kp | Since you're doing this to an arbitrary process, there's extra work involved if you decide to patch the IAT (which you'll probably want to do from in-process anyway, via a hook DLL (HDL)). Specifically, you need to find all loaded modules that have referenced the functions you want and patch them all. Taking Starcraft as an example: it's easy to get the handle to the Starcraft main image (Starcraft.exe) since it is the main image, but at least some of the networking calls are made in its DLLs (and/or SNPs, which are really just DLLs with a different extension). So, you'd need to enumerate all the DLLs it has loaded and patch them too, or you'll miss some/all of the calls. Depending on ease-of-use requirements, it may very well be simpler to have your program just ask the user to look up and supply what DLLs need to be patched. There's at least one way to enumerate the DLLs, but I've never been able to make it work programmatically. It clearly does though, as I've seen debuggers do it. :) | December 15, 2003, 6:50 PM |
Telos | A while back I wrote something to list processes and their modules with sample output like this [quote] Process: 00000444 Module [Load Address]: 00400000 Name: EternalChat.exe Image Size: 757760 Entry Point: 00403e9c Module [Load Address]: 77f40000 Name: ntdll.dll Image Size: 761856 Entry Point: 00000000 Module [Load Address]: 77e40000 Name: kernel32.dll Image Size: 999424 Entry Point: 77e4a342 Module [Load Address]: 73570000 Name: MSVBVM60.DLL Image Size: 1392640 Entry Point: 73571ae8 Module [Load Address]: 77d00000 Name: USER32.dll Image Size: 585728 Entry Point: 77d01b15 Module [Load Address]: 77c00000 Name: GDI32.dll Image Size: 278528 Entry Point: 77c01bbe Module [Load Address]: 77da0000 Name: ADVAPI32.dll Image Size: 589824 Entry Point: 77da1aa6 Module [Load Address]: 77c50000 Name: RPCRT4.dll Image Size: 671744 Entry Point: 77c57fa0 Module [Load Address]: 77160000 Name: ole32.dll Image Size: 1196032 Entry Point: 77161943 Module [Load Address]: 77ba0000 Name: msvcrt.dll Image Size: 344064 Entry Point: 77baedaa Module [Load Address]: 770e0000 Name: OLEAUT32.dll Image Size: 512000 Entry Point: 7714cb43 Module [Load Address]: 744f0000 Name: MSCTF.dll Image Size: 307200 Entry Point: 744f1416 Module [Load Address]: 76f90000 Name: CLBCatQ.DLL Image Size: 516096 Entry Point: 76f93486 Module [Load Address]: 77010000 Name: COMRes.dll Image Size: 811008 Entry Point: 77011048 Module [Load Address]: 77b90000 Name: VERSION.dll Image Size: 32768 Entry Point: 77b91140 Module [Load Address]: 27580000 Name: mscomctl.ocx Image Size: 1069056 Entry Point: 27593990 Module [Load Address]: 762b0000 Name: comdlg32.dll Image Size: 290816 Entry Point: 762b1620 Module [Load Address]: 77290000 Name: SHLWAPI.dll Image Size: 299008 Entry Point: 772922fb Module [Load Address]: 70bc0000 Name: COMCTL32.dll Image Size: 589824 Entry Point: 70c1f668 Module [Load Address]: 77380000 Name: SHELL32.dll Image Size: 8245248 Entry Point: 77382425 Module [Load Address]: 70ad0000 Name: comctl32.dll Image Size: 942080 Entry Point: 70ad41c5 Module [Load Address]: 76300000 Name: msi.dll Image Size: 2179072 Entry Point: 7630649c Module [Load Address]: 22170000 Name: mswinsck.ocx Image Size: 114688 Entry Point: 22171344 Module [Load Address]: 71bb0000 Name: WSOCK32.dll Image Size: 36864 Entry Point: 71bb1060 Module [Load Address]: 71c00000 Name: WS2_32.dll Image Size: 98304 Entry Point: 71c01580 Module [Load Address]: 71bf0000 Name: WS2HELP.dll Image Size: 32768 Entry Point: 71bf132a Module [Load Address]: 20000000 Name: RICHTX32.OCX Image Size: 204800 Entry Point: 200015fd [/quote] If this will be useful at all I will share the code. | December 15, 2003, 10:32 PM |
Kp | I'd be interested in seeing at least the calls that retrieved the information. My recollection is that I found how you're supposed to do it, but attempting to do it failed rather badly and I never had a chance to find out why. | December 15, 2003, 11:09 PM |
Telos | http://www.geocities.com/telosx7/ProcessInformation.htm Edit: Could be shortened a lot by doing everything in the same loop rather than doing the access checks and then copying. | December 16, 2003, 12:04 AM |
Skywing | [quote author=Telos link=board=23;threadid=4256;start=0#msg35599 date=1071533050] http://www.geocities.com/telosx7/ProcessInformation.htm [/quote] You should keep the process handles open between your loops, otherwise you are vulnerable due to a race condition. Process objects will be deleted when there are no handles to them and they are terminated, so you need to keep a handle open to prevent a process ID from being reused or otherwise invalidated. | December 16, 2003, 12:07 AM |
UserLoser. | Speaking of this, I think it'd be neat and very useful if someone were to write a packet logger specifically for protocols such as Battle.net's. Where the user would see the entire packet recieved & sent, along with it taken apart byte by byte, dword by dword, ect; explaining what each byte/word/dword/string is for | December 16, 2003, 12:50 AM |
Kp | [quote author=UserLoser. link=board=23;threadid=4256;start=0#msg35617 date=1071535834] Speaking of this, I think it'd be neat and very useful if someone were to write a packet logger specifically for protocols such as Battle.net's. Where the user would see the entire packet recieved & sent, along with it taken apart byte by byte, dword by dword, ect; explaining what each byte/word/dword/string is for[/quote] IMO, much of the reason this hasn't happened is due to the following: 1) Not much demand 2) The only ones who could do it quickly can analyze the packets by sight, so have no need of a tool to do it for us. Also, if it were to be a true packet logger for the TCP stream, that'd be a much bigger nuisance than just something which can take a precaptured packet and present it in appropriate form. | December 16, 2003, 4:16 AM |
Telos | I was not sure if this was the place to post this but I found an odd behavior in EnumProcessModules. When I pass my array of HMODULEs to the call in order to be filled if it does not contain enough members then [this does not seem to be documented] various other data members in the program are overwritten. In my case the overwritten variable was the DWORD count of processes so the program started trying to close HANDLEs that were not there and access memory at an array index far past the end. I did not test but this behavior may also affect EnumProcesses. On the other note I updated the program so that it will not be vulnerable to race conditions http://www.geocities.com/telosx7/source/procinfo/ProcessInformation.htm. Thanks Skywing. | December 16, 2003, 4:11 PM |
UserLoser. | [quote author=Kp link=board=23;threadid=4256;start=0#msg35654 date=1071548211] [quote author=UserLoser. link=board=23;threadid=4256;start=0#msg35617 date=1071535834] Speaking of this, I think it'd be neat and very useful if someone were to write a packet logger specifically for protocols such as Battle.net's. Where the user would see the entire packet recieved & sent, along with it taken apart byte by byte, dword by dword, ect; explaining what each byte/word/dword/string is for[/quote] IMO, much of the reason this hasn't happened is due to the following: 1) Not much demand 2) The only ones who could do it quickly can analyze the packets by sight, so have no need of a tool to do it for us. Also, if it were to be a true packet logger for the TCP stream, that'd be a much bigger nuisance than just something which can take a precaptured packet and present it in appropriate form. [/quote] Eh, well yesterday i checked vl.com/skywing after I posted this and saw a "Bnparser" that he's developing. It says "Bnparser is a Network Monitor parser plugin to handle various Battle.net protocols.". Sounds like he's making a program just like this or something similiar | December 16, 2003, 4:52 PM |
Skywing | [quote author=UserLoser. link=board=23;threadid=4256;start=0#msg35737 date=1071593542] [quote author=Kp link=board=23;threadid=4256;start=0#msg35654 date=1071548211] [quote author=UserLoser. link=board=23;threadid=4256;start=0#msg35617 date=1071535834] Speaking of this, I think it'd be neat and very useful if someone were to write a packet logger specifically for protocols such as Battle.net's. Where the user would see the entire packet recieved & sent, along with it taken apart byte by byte, dword by dword, ect; explaining what each byte/word/dword/string is for[/quote] IMO, much of the reason this hasn't happened is due to the following: 1) Not much demand 2) The only ones who could do it quickly can analyze the packets by sight, so have no need of a tool to do it for us. Also, if it were to be a true packet logger for the TCP stream, that'd be a much bigger nuisance than just something which can take a precaptured packet and present it in appropriate form. [/quote] Eh, well yesterday i checked vl.com/skywing after I posted this and saw a "Bnparser" that he's developing. It says "Bnparser is a Network Monitor parser plugin to handle various Battle.net protocols.". Sounds like he's making a program just like this or something similiar [/quote] I haven't really worked on that for awhile now, though. Not sure if it'll ever get to a useable state. | December 16, 2003, 4:53 PM |
Arsenic | [quote author=Kp link=board=23;threadid=4256;start=0#msg35515 date=1071514221] there's extra work involved if you decide to patch the IAT (which you'll probably want to do from in-process anyway, via a hook DLL (HDL)). Specifically, you need to find all loaded modules that have referenced the functions you want and patch them all. [/quote] Also, if the application loads the Winsock DLL at run-time, you won't find the reference in the IAT of the executable or its modules. So if you want to have an efficicient sniffer you will have to play with the Winsock DLL directly in the target process memory, or then intercept its loading at run-time. | December 19, 2003, 4:51 AM |
Arta | That's a good point. It might be worth hooking the process's LoadLibrary import (if it exists) and patching DLLs as they're loaded. | December 19, 2003, 6:23 AM |
Adron | You still won't get the ones that aren't dynamically loaded. And you can't attach after the program is already running. The way I like to do it is to patch winsock itself, the entry-points, to jump to your hooks. That's the way WSHook.dll does it! | December 19, 2003, 12:38 PM |
taylorjonl | This is a little project I ran into while searching the internet. http://www.codeproject.com/dll/apihijack.asp#xx590524xx Hope it is helpful. | December 20, 2003, 4:03 PM |
CupHead | That does look helpful, thanks. | December 20, 2003, 5:37 PM |
Meeks | Yea IMO, the most appropriate solution here is called several things, one of which is Extended Code Overwriting another is Detouring, there's a few more but it's all the same thing. This is by no means exact, it is just a brief synapsis: * This is a 32 bit implementation. * Always pay respect to memory. Use VirtualProtect to obtain the correct access rights before writing to memory. * A trampoline function is a function that you allocate space for and it matches the parameters of your target function you want to hook. It's intention is to preserve the bytes you will have to overwrite in order to perform the hook. 1. Copy the first 5 bytes to the trampoline function. 2. Write an unconditional JMP instruction to the trampoline function. 3. Write the 32 bit address of the 6th byte of the target function to the trampoline function. * Pay very careful attention not to cut an assembly instruction off. If you do, you will cause uncontrolled behavior. The number of bytes you will copy from the target function to the trampoline function depends upon the assembly instructions, so open up OllyDbg. * A Detour function is one that is called in place of the target function. * Be sure the target function and your Detour function have identical parameters and are of the same calling convention. 4. Overwrite the first byte of the target function with an unconditional JMP instruction. 5. Overwrite the next 4 bytes with the 32 bit address of your Detour function. Now when the target function is called, it is rerouted to your Detour function, add the changes needed or simply log the activity, now you may call the trampoline function to execute the original target functions contents. It really is as simple as that. There are several examples including source code. Hope this helps. | February 13, 2008, 11:14 PM |
ColT | Great post Meeks, only 5 years later. | February 13, 2008, 11:51 PM |
Spht | I think he's from the future. tell us, saddam hussein was captured last week. what ends up happening to him? | February 14, 2008, 12:21 AM |
Yegg | At least he provided information of use in the event someone searches for a similar topic and finds this site. | February 14, 2008, 6:21 AM |
Meeks | Wow, how'd I over look that one, lol. Oops. | September 15, 2008, 11:59 PM |