调用未导出的DLL函数C++时发生访问冲突

Access Violation Calling Non-Exported DLL Function C++

本文关键字:C++ 访问冲突 函数 DLL 调用      更新时间:2023-10-16

我正试图访问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  

从程序集中可以清楚地看出,此代码期望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成员函数,它在ECX中传递this指针。

请注意,我不能100%肯定以上所有内容。逆向工程在最好的时候已经足够难了,请记住,我们只使用您提供的信息。