※※※※※※难度级别五星(*****),请极有专研精神的朋友进※※※※※※

flybusflybus 2004-12-08 10:28:24
下面这个邮件我发给了几个大牛人,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 ")
...全文
579 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
hikuers 2004-12-13
  • 打赏
  • 举报
回复
FT
flybusflybus 2004-12-13
  • 打赏
  • 举报
回复
过了周末彻底彻底沉了,最后顶一吧
chinarendotcom 2004-12-10
  • 打赏
  • 举报
回复
楼主挺强的呀。 给牛人写信我想都没有想过。 pfpf
zdleek 2004-12-10
  • 打赏
  • 举报
回复
e文我头疼
CodeProject-Jerry 2004-12-10
  • 打赏
  • 举报
回复
做个记号
an_bachelor 2004-12-10
  • 打赏
  • 举报
回复
你們都N 我Mark&Learn行了吧?
李马 2004-12-10
  • 打赏
  • 举报
回复
强人
yeedward 2004-12-10
  • 打赏
  • 举报
回复
英雄 I服了U
Flood1984 2004-12-10
  • 打赏
  • 举报
回复
五星,不假
顶一下
qrlvls 2004-12-10
  • 打赏
  • 举报
回复
弓虽,只有学习的份儿
不过有得学就不错了,哈哈哈,Thx
hzhxxx 2004-12-10
  • 打赏
  • 举报
回复

看不懂,只能 up
flybusflybus 2004-12-10
  • 打赏
  • 举报
回复
zyp2kyear(E腾鸟) 你看核心编程比较仔细,可惜我那罗嗦冗长的邮件你并没仔细看

MissYouChenMin(破解各类软件,联系QQ:14322807)
原因邮件里写了(Question 1)

希望有更深刻的见解出现,我问的问题可能书上招不到答案,很期待有经验的老鸟出来
Mr-Chen 2004-12-10
  • 打赏
  • 举报
回复
先mark一下
MissYouChenMin 2004-12-10
  • 打赏
  • 举报
回复
为什么不用def文件???
zyp2kyear 2004-12-10
  • 打赏
  • 举报
回复
当我们的函数使用__stdcall(WINAPI)的调用规则时,会出现一个问题.Microsoft的C编译器会损害C函数,设置一个前导下化线,在加一个@,后面加上一个数字,表示作为参数传递给函数的字节数.例如
__declspec(dllexport) LONG __stdcall MyFunc(int a, int b)

这个会在Dll中输出函数_Myfunc@8. 因此当用户做了一个可执行模块,调用此DLL的MyFunc就会失败,因为找不到此函数.有两种方法可以实现,一是建立一个.def文件,在其中定义
EXPORTS
MyFunc
第二种方法是在DLL原代码文件中加入
#pragma comment(linker, "/export:MyFunc=_MyFunc@8")
第二种方法中,DLL实际上输出用于标识单个函数的两个符号, 只不过是避免你使用 .def文件而已
zyp2kyear 2004-12-10
  • 打赏
  • 举报
回复
草草的看了一下,感觉楼主是在钩ws2_32.dll的某些函数,放在自己的dll中,供jave应用程序来使用,不知道是不是这个意思。偶没有用过java,但是在WINDOWS下编写和调用Dll是大同小异,下面是用DUMPBIN查看WS2_32.dll看到的。RVA这一列下面的数字用于指明在DLL文件映像中的什么位置能够找到输出符号的位移量。序号列可以与16位Windows源代码向后兼容,并且它不应该用于现在的应用程序中。hint提示码)列可供系统用来改进代码的运行性能,在此并不重要。
注意(我不知道你是否是这个原因导致失败):许多开发人员常常通过为函数赋予一个序号值来输出DLL函数。对于那些来自16位Windows环境的函数来说,情况尤其是如此。但是, Microsoft并没有公布系统DLL的序号值。当你的可执行模块或DLL模块链接到任何一个Windows函数时,Microsoft要求你使用符号的名字进行链接。如果你按照序号进行链接,那么你的应用程序有可能无法在其他Windows平台或将来的Windows平台上运行。

Microsoft (R) COFF Binary File Dumper Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.


Dump of file ws2_32.dll

File Type: DLL

Section contains the following exports for WS2_32.dll

0 characteristics
3A1B81FA time date stamp Wed Nov 22 16:21:14 2000
0.00 version
1 ordinal base
500 number of functions
109 number of names

ordinal hint RVA name

500 0 0000E180 WEP
25 1 0000D852 WPUCompleteOverlappedRequest
26 2 0000CC69 WSAAccept
27 3 0000B6D9 WSAAddressToStringA
28 4 0000B5B3 WSAAddressToStringW
102 5 00007D61 WSAAsyncGetHostByAddr
103 6 00007CBD WSAAsyncGetHostByName
105 7 00007DFA WSAAsyncGetProtoByName
104 8 00007E9E WSAAsyncGetProtoByNumber
107 9 00007B9A WSAAsyncGetServByName
106 A 00007C44 WSAAsyncGetServByPort
101 B 0000C055 WSAAsyncSelect
108 C 00007F11 WSACancelAsyncRequest
113 D 00005B04 WSACancelBlockingCall
116 E 0000DB55 WSACleanup
29 F 000070A9 WSACloseEvent
30 10 0000C96F WSAConnect
31 11 0000710F WSACreateEvent
32 12 000069CE WSADuplicateSocketA
33 13 00006927 WSADuplicateSocketW
34 14 0000A717 WSAEnumNameSpaceProvidersA
35 15 0000A770 WSAEnumNameSpaceProvidersW
36 16 0000CA22 WSAEnumNetworkEvents
37 17 00006EAC WSAEnumProtocolsA
38 18 00006A20 WSAEnumProtocolsW
39 19 0000BFAE WSAEventSelect
111 1A 00001292 WSAGetLastError
40 1B 0000CAC9 WSAGetOverlappedResult
41 1C 00009552 WSAGetQOSByName
42 1D 0000B3F7 WSAGetServiceClassInfoA
43 1E 0000B482 WSAGetServiceClassInfoW
44 1F 0000B00F WSAGetServiceClassNameByClassIdA
45 20 0000B209 WSAGetServiceClassNameByClassIdW
46 21 000049C8 WSAHtonl
47 22 00004AD8 WSAHtons
48 23 0000ADD5 WSAInstallServiceClassA
49 24 0000AE4D WSAInstallServiceClassW
50 25 00001D7B WSAIoctl
114 26 00005B4C WSAIsBlocking
58 27 0000CFD8 WSAJoinLeaf
59 28 0000A7C9 WSALookupServiceBeginA
60 29 0000A86E WSALookupServiceBeginW
61 2A 0000AACB WSALookupServiceEnd
62 2B 0000A92A WSALookupServiceNextA
63 2C 0000AA31 WSALookupServiceNextW
64 2D 00004BD7 WSANtohl
65 2E 00004CE7 WSANtohs
66 2F 00006FDD WSAProviderConfigChange
67 30 00001209 WSARecv
68 31 0000A368 WSARecvDisconnect
69 32 0000A3EB WSARecvFrom
70 33 0000AF2E WSARemoveServiceClass
71 34 0000711D WSAResetEvent
72 35 000019F3 WSASend
73 36 0000C297 WSASendDisconnect
74 37 0000C329 WSASendTo
109 38 00005B76 WSASetBlockingHook
75 39 0000712A WSASetEvent
112 3A 00009545 WSASetLastError
76 3B 0000AB2A WSASetServiceA
77 3C 0000AC5E WSASetServiceW
78 3D 0000CBFD WSASocketA
79 3E 000016E9 WSASocketW
115 3F 00003E15 WSAStartup
80 40 0000B977 WSAStringToAddressA
81 41 0000B890 WSAStringToAddressW
110 42 00005BCB WSAUnhookBlockingHook
82 43 00007137 WSAWaitForMultipleEvents
24 44 0000DC46 WSApSetPostRoutine
83 45 0000D42A WSCDeinstallProvider
84 46 00008A2E WSCEnableNSProvider
85 47 00003731 WSCEnumProtocols
86 48 00006E94 WSCGetProviderPath
87 49 0000875C WSCInstallNameSpace
88 4A 0000D0F5 WSCInstallProvider
89 4B 000088F7 WSCUnInstallNameSpace
90 4C 00008BF5 WSCWriteNameSpaceOrder
91 4D 0000D616 WSCWriteProviderOrder
151 4E 00001BF5 __WSAFDIsSet
1 4F 0000CC51 accept
2 50 00001E77 bind
3 51 000013B6 closesocket
4 52 0000C453 connect
51 53 000075E0 gethostbyaddr
52 54 000076B8 gethostbyname
57 55 000077AF gethostname
5 56 0000C553 getpeername
53 57 000071D3 getprotobyname
54 58 00007153 getprotobynumber
55 59 000079B2 getservbyname
56 5A 000078C8 getservbyport
6 5B 0000C5FA getsockname
7 5C 00001ABC getsockopt
8 5D 00001E2E htonl
9 5E 000012B0 htons
11 5F 0000463C inet_addr
12 60 00004893 inet_ntoa
10 61 00007FFE ioctlsocket
13 62 0000C7F0 listen
14 63 00001E2E ntohl
15 64 000012B0 ntohs
16 65 0000A1AE recv
17 66 00002097 recvfrom
18 67 00001F3B select
19 68 0000C10F send
20 69 00002147 sendto
21 6A 000018BC setsockopt
22 6B 00001979 shutdown
23 6C 00001EF4 socket

Summary

1000 .data
1000 .reloc
1000 .rsrc
F000 .text
flybusflybus 2004-12-10
  • 打赏
  • 举报
回复
同志们,有没有人能给点有价值得意见啊?
hjunxu 2004-12-09
  • 打赏
  • 举报
回复
FT
的确很深奥。
看不懂。
zxwitsme 2004-12-09
  • 打赏
  • 举报
回复
up
camelyi 2004-12-09
  • 打赏
  • 举报
回复
看英文就头大
加载更多回复(14)

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧