※※※※※※难度级别五星(*****),请极有专研精神的朋友进※※※※※※
下面这个邮件我发给了几个大牛人,jeffery也给了我一些建议,不过他老人家已经太久没有写c++程序了,所以只是给了一些我实际已经了解的建议(不过jeffery的确是一位非常伟大的程序员,我从他的著作和技术文章中学到很多东西,他多次直接给予我帮助的时候同样显得非常无私和专业),似乎跑题了,下面的邮件中提到的问题不知有哪位大虾能帮忙解答一把,先谢了!
(英文粗糙,不过既然外国人能看懂,我想咱也没问题)
Here I want to write a Apihook to hook several api from ws2_32.dll,
when my java program run. But when I test it, I found javaw loads ws2_32.dll
dynamically, and it seems like javaw have saved the api's address, so, I th-
inked I must hook "GetProcAddress" and retrun my stub fun's address instead
of the real api's address. By some reason,I don't wanna use this ways , so
I choosed another way(Troy) which you showed in your great book Programming
Applications for Microsoft Windows,Fourth Edition.
There are more than one hundreds of apis exported by ws2_32.dll,and I
don't wanna define so many stub functions, what I need is just replace
very few of them ,so I used something like
'#pragma comment(linker, "/export:accept=real_ws2_32.dll.accept") '
to avoid define the other funs. By using UltraEdit.exe and depends.exe,I built
a big list very quickly, but when I used the dll I built,I meet some questions.
Question 1. The ordinal in my own ws2_32.dll is different from the system
ws2_32.dll(it seems like the exported funs is sorted default wih de-
nominator). For example,the ordinal of "bind" in system ws2_32.dll is 2,
which is 81 in my own ws2_32.dll, so when javaw call "bind", it will not
call the right one,but something like "WEP"(if the WEP's ondinal is pr-
ecisely 2 in my own ws2_32.dll), I know I could export my stub fun with the
same ordinary as the ordinary in real ws2_32.dll by a .def file like:
LIBRARY WS2_32
EXPORTS
bind @2
...
but if I use .def file ,I coun't use the #pragma to export my fun, which
way I use to avoid from defination of so many funs. Is there any anything
like '#pragma comment(linker,"/export:accept=real_ws2_32.dll.accept @1")'
or some way to exports functions redirect to another dll by file ".def" .
what I strived is to avoid to define the whole apis from ws2_32.dll (what
I want to hook is very few of them)
Question 2. Using #pragma, I can not use something like extern "C". When I
build a test program and linked with my own ws2_32.lib ,there will raise link
error like: "unresolved external symbol _bind@12", so I tryed
#pragma comment(linker, "/export:_bind@12=real_ws2_32.dll.accept")
and
#pragma comment(linker, "/export:_bind@12=real_ws2_32.dll._bind@12")
first one can't compily success(when build my own ws2_32.dll), for
sencond one , there no _bind@12 in real_ws2_32.dll indeed. I don't know
is there any way to resolve this or in fact there are not any need to use my
own ws2_32.lib but the ws2_32.lib provided by system.
If I compily my test program, and link with the ws2_32.lib provided by
system. When I run it, the code---------
'GetProcAddress(GetModuleHandle("ws2_32.dll"),MAKEINTRESOURCE(13));'
will return NULL, if there is a funcion exported by my own ws2_32.dll forwarded
to real_ws2_32.dll hold ordinary 13, or it will return not null ,if I use file
.def export a function use the ordinary 13 (it will return the function's addr).
the code---------
'GetProcAddress(GetModuleHandle("ws2_32.dll"),"listen");'
will return null too, if I just forward "listen" to real_ws2_32.dll.
When I use code
'GetProcAddress(GetModuleHandle("kernel32.dll"),"HeapAlloc");
it will not return null, I know HeapAlloc is forwarded to NTDLL.RtlAllocateHeap,
I don't konw what make all this happen.
#######################################################################################
Below is my code piece: (use this code I build a dll named ws2_32.dll, ##
and I copyed the real ws2_32.dll from SystemDirectory, and changed its name ##
with real_ws2_32.dll, then I put the 2 dlls into the same directory with ##
javaw.exe. In this way, when javaw call api(for example recv) it will call ##
my stub fun if I redefined it in my own ws2_32.dll, or call the real api in ##
real_ws2_32.dll if I just forward it to real ws2_32.dll in my own ws2_32.dll.) ##
#######################################################################################
//*************************/BEGIN\*****************************
#include <windows.h>
extern "C"
{
//exported by .def
SOCKET PASCAL FAR accept (SOCKET s, struct sockaddr FAR *addr,
int FAR *addrlen)
{
static HMODULE hModule = GetModuleHandle("real_ws2_32.dll");
if(!hModule) hModule = LoadLibrary("real_ws2_32.dll");
static PfnAccept pfnaccept = (PfnAccept) GetProcAddress(hModule,"accept");
return pfnaccept ? (*pfnaccept)(s,addr,addrlen) : -1;
}
//-------------------define other apis which I want to observe......
}
//#pragma comment(linker, "/export:accept=real_ws2_32.dll.accept")
#pragma comment(linker, "/export:bind=real_ws2_32.dll.bind")
#pragma comment(linker,"/export:closesocket=real_ws2_32.dll.closesocket")
#pragma comment(linker, "/export:connect=real_ws2_32.dll.connect")
#pragma comment(linker,"/export:getpeername=real_ws2_32.dll.getpeername")
#pragma comment(linker, "/export:getsockname=real_ws2_32.dll.getsockname")
#pragma comment(linker, "/export:getsockopt=real_ws2_32.dll.getsockopt")
#pragma comment(linker, "/export:htonl=real_ws2_32.dll.htonl ")
#pragma comment(linker, "/export:htons=real_ws2_32.dll.htons ")
#pragma comment(linker, "/export:ioctlsocket=real_ws2_32.dll.ioctlsocket")
#pragma comment(linker, "/export:inet_addr=real_ws2_32.dll.inet_addr ")
#pragma comment(linker, "/export:inet_ntoa=real_ws2_32.dll.inet_ntoa ")