访问冲突调用非导出的DLL函数C ++

时间:2014-11-12 19:46:50

标签: c++ assembly reverse-engineering access-violation

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

1 个答案:

答案 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%确定以上所有内容。逆向工程在最好的时候是很难的,并且要记住我们正在处理您提供的信息。