当然可能依靠钩功能,但是如果我们知道这个序数。
总的来说序数不稳定。所以例如Sleep
在每个Windows版本中都有不同的序号。甚至更多 - 在相同的寡妇版本中,它在kernel32.dll
的x86和x64版本中具有不同的序号 - 但在您的应用程序中,Sleep
按序号按序号?我100%确定没有。
但是有些序数是稳定的,在一些dll中(如ws2_32.dll
或oleaut32.dll
)。我们如何知道哪些序数是稳定的(可以使用)?让我们想想 - 我们使用链接someimport.lib
作为导入函数some.dll
- 在此导入LIB
中,并且包含信息如何导入函数 - 按名称或按顺序。所以你需要从LIB
文件中获取信息。这可以通过命令来完成:
link.exe -dump /EXPORTS "somepath\somelib.lib" > somelib.log
让利例如采取ws2_32.lib
- 我运行
link.exe -dump /EXPORTS "my path\x64\ws2_32.lib" > ws2_32.log
ordinal name
[email protected]@[email protected] (int __cdecl WSApSetPostRoutine(void *))
FreeAddrInfoEx
FreeAddrInfoExW
FreeAddrInfoW
GetAddrInfoExA
GetAddrInfoExCancel
GetAddrInfoExOverlappedResult
GetAddrInfoExW
GetAddrInfoW
GetHostNameW
GetNameInfoW
InetNtopW
InetPtonW
SetAddrInfoExA
SetAddrInfoExW
500 WEP
WPUCompleteOverlappedRequest
WPUGetProviderPathEx
WSAAccept
WSAAddressToStringA
WSAAddressToStringW
WSAAdvertiseProvider
102 WSAAsyncGetHostByAddr
103 WSAAsyncGetHostByName
105 WSAAsyncGetProtoByName
104 WSAAsyncGetProtoByNumber
107 WSAAsyncGetServByName
106 WSAAsyncGetServByPort
101 WSAAsyncSelect
108 WSACancelAsyncRequest
113 WSACancelBlockingCall
116 WSACleanup
WSACloseEvent
WSAConnect
WSAConnectByList
WSAConnectByNameA
WSAConnectByNameW
WSACreateEvent
WSADuplicateSocketA
WSADuplicateSocketW
WSAEnumNameSpaceProvidersA
WSAEnumNameSpaceProvidersExA
WSAEnumNameSpaceProvidersExW
WSAEnumNameSpaceProvidersW
WSAEnumNetworkEvents
WSAEnumProtocolsA
WSAEnumProtocolsW
WSAEventSelect
111 WSAGetLastError
WSAGetOverlappedResult
WSAGetQOSByName
WSAGetServiceClassInfoA
WSAGetServiceClassInfoW
WSAGetServiceClassNameByClassIdA
WSAGetServiceClassNameByClassIdW
WSAHtonl
WSAHtons
WSAInstallServiceClassA
WSAInstallServiceClassW
WSAIoctl
114 WSAIsBlocking
WSAJoinLeaf
WSALookupServiceBeginA
WSALookupServiceBeginW
WSALookupServiceEnd
WSALookupServiceNextA
WSALookupServiceNextW
WSANSPIoctl
WSANtohl
WSANtohs
WSAPoll
WSAProviderCompleteAsyncCall
WSAProviderConfigChange
WSARecv
WSARecvDisconnect
WSARecvFrom
WSARemoveServiceClass
WSAResetEvent
WSASend
WSASendDisconnect
WSASendMsg
WSASendTo
109 WSASetBlockingHook
WSASetEvent
112 WSASetLastError
WSASetServiceA
WSASetServiceW
WSASocketA
WSASocketW
115 WSAStartup
WSAStringToAddressA
WSAStringToAddressW
WSAUnadvertiseProvider
110 WSAUnhookBlockingHook
WSAWaitForMultipleEvents
WSCDeinstallProvider
WSCDeinstallProvider32
WSCDeinstallProviderEx
WSCEnableNSProvider
WSCEnableNSProvider32
WSCEnumNameSpaceProviders32
WSCEnumNameSpaceProvidersEx32
WSCEnumProtocols
WSCEnumProtocols32
WSCEnumProtocolsEx
WSCGetApplicationCategory
WSCGetApplicationCategoryEx
WSCGetProviderInfo
WSCGetProviderInfo32
WSCGetProviderPath
WSCGetProviderPath32
WSCInstallNameSpace
WSCInstallNameSpace32
WSCInstallNameSpaceEx
WSCInstallNameSpaceEx2
WSCInstallNameSpaceEx32
WSCInstallProvider
WSCInstallProvider64_32
WSCInstallProviderAndChains64_32
WSCInstallProviderEx
WSCSetApplicationCategory
WSCSetApplicationCategoryEx
WSCSetProviderInfo
WSCSetProviderInfo32
WSCUnInstallNameSpace
WSCUnInstallNameSpace32
WSCUnInstallNameSpaceEx2
WSCUpdateProvider
WSCUpdateProvider32
WSCUpdateProviderEx
WSCWriteNameSpaceOrder
WSCWriteNameSpaceOrder32
WSCWriteProviderOrder
WSCWriteProviderOrder32
WSCWriteProviderOrderEx
WahCloseApcHelper
WahCloseHandleHelper
WahCloseNotificationHandleHelper
WahCloseSocketHandle
WahCloseThread
WahCompleteRequest
WahCreateHandleContextTable
WahCreateNotificationHandle
WahCreateSocketHandle
WahDestroyHandleContextTable
WahDisableNonIFSHandleSupport
WahEnableNonIFSHandleSupport
WahEnumerateHandleContexts
WahInsertHandleContext
WahNotifyAllProcesses
WahOpenApcHelper
WahOpenCurrentThread
WahOpenHandleHelper
WahOpenNotificationHandleHelper
WahQueueUserApc
WahReferenceContextByHandle
WahRemoveHandleContext
WahWaitForNotification
WahWriteLSPEvent
151 __WSAFDIsSet
1 accept
2 bind
3 closesocket
4 connect
freeaddrinfo
getaddrinfo
51 gethostbyaddr
52 gethostbyname
57 gethostname
getnameinfo
5 getpeername
53 getprotobyname
54 getprotobynumber
55 getservbyname
56 getservbyport
6 getsockname
7 getsockopt
8 htonl
9 htons
11 inet_addr
12 inet_ntoa
inet_ntop
inet_pton
10 ioctlsocket
13 listen
14 ntohl
15 ntohs
16 recv
17 recvfrom
18 select
19 send
20 sendto
21 setsockopt
22 shutdown
23 socket
如果我们查看顺序不是空的 - API将通过序导入( 如果PE通过链接与这个lib)如果是空的 - 将按名称导入。所以例如WSAStartup
将按顺序115(0x73)导入,当WSASocketW
将按名称导入时。如果Microsoft库(ws2_32.lib
)通过序号115导出WSAStartup
- 这意味着在所有的Windows(x64)版本中WSAStartup
必须必须以相同序号115导出 - 否则与此官方lib链接的应用程序数量很大 - 在运行时未启动或崩溃。所以在未来,一些ws2_32.lib
的另一个版本可以开始导入WSAStartup
的名称,但所有窗口ws2_32.dll
已经必须始终导出WSAStartup
与115序数。
如果您检查kernel32.lib
您可以查看该序号列全部为空 - 因此没有任何承授人关于说Sleep
序号 - 它确实非常波动。
那么需要怎么写代码,例如检测到WSAStartup
的导入条目?
#define WSAStartup_Ordinal 115
PVOID hmod;
PIMAGE_IMPORT_DESCRIPTOR piid;
ULONG size/* size of IMPORT directory*/, d;
// assume hmod, piid, size already initialized
while ((INT)size >= sizeof(IMAGE_IMPORT_DESCRIPTOR) && (d = piid->Name))
{
PCSTR name = RtlOffsetToPointer(hmod, d);
if (!_stricmp(name, "ws2_32.dll"))
{
if (d = piid->FirstThunk)
{
PIMAGE_THUNK_DATA FirstThunk = (PIMAGE_THUNK_DATA)RtlOffsetToPointer(hmod, d);
if (d = piid->OriginalFirstThunk)
{
PIMAGE_THUNK_DATA OriginalFirstThunk = (PIMAGE_THUNK_DATA)RtlOffsetToPointer(hmod, d);
while (ULONG_PTR Ordinal = OriginalFirstThunk->u1.Ordinal)
{
ULONG_PTR Function = 0;
if (IMAGE_SNAP_BY_ORDINAL(Ordinal))
{
if (IMAGE_ORDINAL(Ordinal) == WSAStartup_Ordinal) // 115
{
Function = FirstThunk->u1.Function;
}
}
else
{
if (!strcmp((PCSTR)((PIMAGE_IMPORT_BY_NAME)RtlOffsetToPointer(hmod, Ordinal))->Name, "WSAStartup"))
{
Function = FirstThunk->u1.Function;
}
}
if (Function)
{
__nop();
}
}
}
}
}
size -= sizeof(IMAGE_IMPORT_DESCRIPTOR), piid++;
}
@user - 你完全错了 - 序号不稳定。我们不能使用序数进行睡眠 - 它在不同的Windows版本中有所不同。 – RbMm
@RbMm哦okey谢谢。如果我们说睡眠是按顺序导入的,通过IAT挂钩该功能,还有其他解决方案吗? –
睡眠永远不会按顺序导入 - 这是不正确的。但我当然知道解决方案 – RbMm