问题是我在应用程序导入的dll上找不到任何可疑功能。因此,我试图在对话框中查找对密码进行加密的字符串。但是,该程序的所有对话框都存储在dll的资源部分中(似乎它们为不同的语言提供了不同的dll)。在Ghidra上打开该dll时,我可以看到字符串,但是找不到哪个函数调用它们。使用ResEdit,我设法获得了对话框和字符串的ID,但是如何将这些ID与调用它们的函数进行匹配?有什么方法可以仅通过静态分析来完成,还是需要使用OllyDbg?另外,更糟糕的是,包含字符串和对话框的dll未在主.exe的import部分中列出,也未在任何已导入dll的任何import部分中列出。我设法找到了动态导入资源dll的主.exe的功能。我想这将使仅通过静态分析更难找到匹配项,对吗?有什么提示吗?谢谢!
#1 楼
要解决此问题,您需要了解如何通过Windows API加载资源。通常使用kernel32.dll中的许多API,例如:使用Kernel32.dll中的许多API例如:
LoadLibrary
LoadLibraryEx
GetModuleHandle
FindResource
FindResourceEx
LockResource
FreeResource
SizeofResource
以及用于对话框/窗口user32.dll中使用了其他API,例如:
RegisterClassEx
DialogBoxParam
LoadAccelerators
LoadIcon
LoadImage
LoadMenu
LoadCursor
LoadString
用32位代码编写的简单LoadString API可能看起来像这样,其中101是字符串ID。
mov DWORD PTR _stringID$[ebp], 101 ; string ID
mov DWORD PTR _pBuf$[ebp], 0
push 0
lea eax, DWORD PTR _pBuf$[ebp] ; put location to store result in eax
push eax
mov ecx, DWORD PTR _stringID$[ebp] ; string ID = 101
push ecx
mov edx, DWORD PTR _hInstance$[ebp] ; hInstance
push edx
call DWORD PTR __imp__LoadStringW@16
mov DWORD PTR _len$[ebp], eax ; eax holds length of string
在64位代码中可能看起来像这样:
mov DWORD PTR stringID$[rsp], 101 ; string ID
mov QWORD PTR pBuf$[rsp], 0
xor r9d, r9d
lea r8, QWORD PTR pBuf$[rsp] ; put location to store result in r8
mov edx, DWORD PTR stringID$[rsp] ; string ID = 101
mov rcx, QWORD PTR hInstance$[rsp] ; hInstance
call QWORD PTR __imp_LoadStringW
mov DWORD PTR len$[rsp], eax ; length of returned string in EAX
在32位中使用FindResource可能看起来像这样:
push 0
push 10 ; resource type ( 10 = RCDATA section)
push 100 ; 100 = resource ID
mov eax, DWORD PTR _hInstance$[ebp] ; hInstance to module containing resource in EAX
push eax
call DWORD PTR __imp__FindResourceExA@16
mov DWORD PTR _rc$[ebp], eax ; handle to the specified resource's information block returned in EAX
mov ecx, DWORD PTR _rc$[ebp] ; specify resource information block handle in ECX
push ecx
mov edx, DWORD PTR _hInstance$[ebp] ; hInstance module with resource
push edx
call DWORD PTR __imp__LoadResource@8
mov DWORD PTR _rcData$[ebp], eax ; hGlobal Handle returned in EAX
mov eax, DWORD PTR _rcData$[ebp] ; specify hGlobal handle in EAX
push eax
call DWORD PTR __imp__LockResource@4
mov DWORD PTR _data$[ebp], eax ; If the loaded resource is available, the return value in EAX is a pointer to the first byte of the resource
mov ecx, DWORD PTR _rc$[ebp] ; resource information block handle
push ecx
mov edx, DWORD PTR _hInstance$[ebp] ; hInstance module with resource
push edx
call DWORD PTR __imp__SizeofResource@8
mov DWORD PTR _size$[ebp], eax ; EAX contains size of resource in bytes
64位FindResource
xor r9d, r9d
mov r8d, 10 ; resource type = 10 = RCDATA
mov edx, 100 ; resource ID = 100
mov rcx, QWORD PTR hInstance$[rsp] ; hInstance to module containing resource
call QWORD PTR __imp_FindResourceExA
mov QWORD PTR rc$[rsp], rax ; handle to the specified resource's information block returned in RAX
mov rdx, QWORD PTR rc$[rsp] ; specify handle to resource information block in RDX
mov rcx, QWORD PTR hInstance$[rsp] ; specify hInstance in RCX
call QWORD PTR __imp_LoadResource
mov QWORD PTR rcData$[rsp], rax ; HGLOBAL returned in RAX
mov rcx, QWORD PTR rcData$[rsp] ; specify HGLOBAL in RCX
call QWORD PTR __imp_LockResource
mov QWORD PTR data$[rsp], rax ; If the loaded resource is available, the return value in RAX is a pointer to the first byte of the resource
mov rdx, QWORD PTR rc$[rsp] ; handle to the specified resource's information block
mov rcx, QWORD PTR hInstance$[rsp] ; hInstance for module containing resource
call QWORD PTR __imp_SizeofResource
mov DWORD PTR size$[rsp], eax ; size of data in bytes returned in EAX
评论
IIRC的某些功能直接获取资源ID,不需要先加载资源,例如创建对话框。
–伊戈尔·斯科钦斯基♦
20 Jan 25 '21:56
评论
我也想提供一种不涉及经典RCE的方法。由于您似乎能够运行二进制文件,因此可以使用WinSpy(在GitHub上)或Spy ++(在Visual Studio中包含)之类的工具来查找正在运行的应用程序的控件ID,并将其与静态分析期间看到的匹配。与吉德拉。还应了解,很可能在内存中建立斑点,这些斑点被理解为对话框资源,依此类推。因此,它根本不需要在资源部分中...