我正在尝试访问DLL中的非导出函数以用于实验目的。没有讨论为什么这是一个坏主意的明显原因......
我相信我已经找到了正确的函数原型,并且我可以确认代码在我想要的模块中跳转到偏移量。
C ++代码是
typedef int (__stdcall *FN)(int,wchar_t *);
const DWORD_PTR funcOffset = 0x6F5B9;
int _tmain(int argc, _TCHAR* argv[])
{
FN myFunction;
DWORD dwResult;
HMODULE hModule=LoadLibrary(L"undocumented.dll");
if (hModule != NULL)
{
DWORD_PTR funcAddress = (DWORD_PTR)GetProcAddress(hModule, "DllRegisterServer") + funcOffset;
myFunction = (FN)funcAddress;
wchar_t input[] = L"someinputdata";
int result = myFunction(0,input);
std::cout << "Result: " << result << std::endl;
}
else
{
dwResult = GetLastError();
std::cerr << "Failed: " << dwResult << std::endl;
}
return 0;
}
函数跳转到偏移量,但我在mov [esi + 8],eax处获得了访问冲突。我该怎么做才能阻止这个
mov edi, edi
push ebp
mov ebp, esp
sub esp, 0Ch
cmp [ebp+<wchar_t *>], 0
push esi
mov esi, ecx
jz short <some location> ; doesn't jump
push [ebp+<wchar_t *>]
call ds:_wcsdup
mov [esi+8], eax <- access violation
Ecx在调用ds:_wcsup:
中设置__wcsdup:
75DBEFA3 mov edi,edi
75DBEFA5 push ebp
75DBEFA6 mov ebp,esp
75DBEFA8 cmp dword ptr [ebp+8],0
75DBEFAC je __wcsdup+2161Ah (75DE05BDh)
75DBEFB2 mov ecx,dword ptr [ebp+8]
75DBEFB5 push edi
75DBEFB6 xor edi,edi
75DBEFB8 lea edx,[ecx+2]
75DBEFBB mov ax,word ptr [ecx]
75DBEFBE add ecx,2
75DBEFC1 cmp ax,di
75DBEFC4 jne __wcsdup+18h (75DBEFBBh)
75DBEFC6 sub ecx,edx
75DBEFC8 sar ecx,1
75DBEFCA push ebx
75DBEFCB push 2
75DBEFCD lea ebx,[ecx+1]
75DBEFD0 push ebx
75DBEFD1 call _calloc (75DBBE55h)
75DBEFD6 mov edi,eax
75DBEFD8 pop ecx
75DBEFD9 pop ecx
75DBEFDA test edi,edi
75DBEFDC je __wcsdup+2161Eh (75DE05C1h)
75DBEFE2 push dword ptr [ebp+8]
75DBEFE5 push ebx
75DBEFE6 push edi
75DBEFE7 call _wcscpy_s (75DBBB70h)
75DBEFEC add esp,0Ch
75DBEFEF test eax,eax
75DBEFF1 jne __wcsdup+5626Fh (75E15212h)
75DBEFF7 mov eax,edi
75DBEFF9 pop ebx
75DBEFFA pop edi
75DBEFFB pop ebp
75DBEFFC ret
答案 0 :(得分:2)
从程序集中可以清楚地看出,此代码需要ECX
中的有意义值。
mov edi, edi
push ebp
mov ebp, esp
sub esp, 0Ch
cmp [ebp+<wchar_t *>], 0
push esi
mov esi, ecx !! ecx has not been written to before here, now it is read
您认为该功能为stdcall
。对于stdcall
函数,ECX
的值在输入时定义不明确。所以我要说很明显该函数不是stdcall
。使用输入参数的唯一明显标志是使用ECX
。所以我要说这是一个thiscall
成员函数,它传递this
中的ECX
指针。
请注意,我无法100%确定以上所有内容。逆向工程在最好的时候是很难的,并且要记住我们正在处理您提供的信息。