我是程序员的新手,目前有可执行文件,我正在调查用于教育目的。我正在使用IDA pro来理解可执行文件的目的,但几乎没有问题。这是我的代码:
1.text:00401525 call ebp ; MapViewOfFile
2.text:00401527 mov ebp, eax
3.text:00401529 test ebp, ebp
4.text:0040152B mov [esp+54h+argv], ebp ; argv-shi ari chemi dll gadmotanili
5.text:0040152F jnz short loc_401538
6.text:00401531 push eax ; Code
7.text:00401532 call ds:exit
8.text:00401538 ; ---------------------------------------------------------------------------
9.text:00401538
10.text:00401538 loc_401538: ; CODE XREF: _main+EFj
11.text:0040154C mov esi, [ebp+3Ch]
12.text:0040154F push ebp
13.text:00401550 add esi, ebp
14.text:00401552 mov ebx, eax
15.text:00401554 push esi
16.text:00401555 mov [esp+68h+var_30], ebx
17.text:00401559 mov ecx, [esi+78h]
18.text:0040155C push ecx
19.text:0040155D call sub_401040
我做了枚举只是为了简化我的问题。
正如您在第1行MapViewofFile
函数中看到的那样,返回地址存储在ebp
中,然后存储在argv
中(只是为了清楚{{1}已被映射)。之后在第11行(据我所知),一些函数指针在kernel32.dll
中移动了。十进制的esi
是3ch
,每个函数是4个字节,我列出了从60
导出的所有函数,发现第15个函数是kernel32.dll
。然后AddSecureMemoryCacheCallback
被推到堆栈上,第13行我完全糊涂了。据我所知,它会将ebp
s的指针添加到指向kernel32.dll
的指针,这是无意义的,但我想不出它可以做什么,这是什么目的?对不起,如果我的问题听起来很傻,我是装配新手,我无法粘贴整个代码,因为它太大了。感谢。
答案 0 :(得分:2)
该函数调用MapViewOfFile
返回值
如果函数成功,则返回值是映射视图的起始地址 如果函数失败,则返回值为NULL。要获取扩展错误信息,请调用GetLastError。
这是优化代码,因此ebp
用作通用寄存器,而不是基指针。
1 call ebp ; MapViewOfFile
2 mov ebp, eax //EBP = start address of mapped view.
3 test ebp, ebp //Success or failure?
4 mov [esp+54h+argv], ebp //save mapped address in a variable
5 jnz short loc_401538 //Success -> jump to loc_401538
6 push eax //failure -> clean up and exit.
7 call ds:exit
8 ---------------------------------------------------------------------------
9
10 loc_401538: ; CODE XREF: _main+EFj
11 mov esi, [ebp+3Ch] //esi = MappedFile.SomeOffset at addr 60 in the mapped file
12 push ebp //Param3 = Addr(MappedFile)
13 add esi, ebp //esi = pointer(MappedFile.SomeOffset)
14 mov ebx, eax //ebx = start of mapped file
15 push esi //Param2 = pointer(MappedFile.SomeOffset)
16 mov [esp+68h+var_30], ebx //store start of mapped file in some var
17 mov ecx, [esi+78h] //ecx = MappedFile.SomeOffset-> = 120
18 push ecx //Param1 = MappedFile.SomeOffset[120]
19 call sub_401040 //call subroutine(Param1, Param2, Param3)
子程序是一个使用cdecl
calling convention的3个参数的函数。 Param2和Param3是指向映射文件的指针,param1是一些未知数据
如果您知道要映射的文件的文件名,那么您可以使用hexeditor查看数据并(可能)查看偏移量60中存储的偏移量,然后计算偏移量中存储的数据:[0+offset[60]][120]
。
请注意,调用的子例程很可能返回一个值,因为eax
可用。
关于您的评论
您假设此代码段调用Kernel32.dll
中的函数不正确。所有指针都指向MapViewOfFile
返回的缓冲区,您必须研究该特定文件的内容以了解代码的作用。
推送寄存器只是工作中的cdecl
调用约定。因为这是c
代码,所以它在内部使用cdecl
调用约定,这需要使用堆栈传输所有参数。
在外部,它使用stdcall
传输寄存器中的前3个参数。
stdcall
和cdecl
都会在EAX
中返回结果。