Valhalla Legends Forums Archive | Advanced Programming | Hooking Winsock

AuthorMessageTime
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

Search