添加两个地址
Adding two addreses
我有可执行文件,出于教育目的我正在对其进行调查。我正在使用 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
中(只是为了清楚kernel32.dll
是正在映射的文件)。
在第 11 行之后(据我所知)一些函数指针被移到了 esi
。 3ch
十进制是60
,每个函数都是4字节,我把kernel32.dll
导出的所有函数都列出来,发现第15个函数是AddSecureMemoryCacheCallback
。然后 ebp
被压入堆栈,在第 13 行我完全糊涂了。据我了解,它会将 kernel32.dll
s 的指针添加到指向 AddSecureMemoryCacheCallback
的指针,这是无稽之谈,但我想不出它能做什么,这样做的目的是什么?抱歉,如果我的问题听起来很愚蠢,我是汇编新手,我无法粘贴整个代码,因为它太大了。谢谢。
函数调用MapViewOfFile
Return value
If the function succeeds, the return value is the starting address of the mapped view.
If the function fails, the return value is NULL. To get extended error information, call 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 是一些未知数据。
如果您知道被映射文件的文件名,那么您可以使用十六进制编辑器查看数据并(可能)查看哪个偏移量存储在偏移量 60 处,然后计算偏移量处存储的数据:[0+offset[60]][120]
.
请注意,调用 return 的子例程很可能是一个值,因为 eax
可用。
关于您的评论
您认为此代码段调用 Kernel32.dll
中的函数的假设是不正确的。所有指针都指向由 MapViewOfFile
编辑的 return 缓冲区,您必须研究该特定文件的内容才能理解代码的作用。
寄存器的推送只是工作中的cdecl
调用约定。因为这是 c
代码,它在内部使用 cdecl
调用约定,要求所有参数都使用堆栈传输。
在外部它使用 stdcall
将前 3 个参数传输到寄存器中。
stdcall
和 cdecl
return 的结果都是 EAX
。
我有可执行文件,出于教育目的我正在对其进行调查。我正在使用 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
中(只是为了清楚kernel32.dll
是正在映射的文件)。
在第 11 行之后(据我所知)一些函数指针被移到了 esi
。 3ch
十进制是60
,每个函数都是4字节,我把kernel32.dll
导出的所有函数都列出来,发现第15个函数是AddSecureMemoryCacheCallback
。然后 ebp
被压入堆栈,在第 13 行我完全糊涂了。据我了解,它会将 kernel32.dll
s 的指针添加到指向 AddSecureMemoryCacheCallback
的指针,这是无稽之谈,但我想不出它能做什么,这样做的目的是什么?抱歉,如果我的问题听起来很愚蠢,我是汇编新手,我无法粘贴整个代码,因为它太大了。谢谢。
函数调用MapViewOfFile
Return value
If the function succeeds, the return value is the starting address of the mapped view.
If the function fails, the return value is NULL. To get extended error information, call 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 是一些未知数据。
如果您知道被映射文件的文件名,那么您可以使用十六进制编辑器查看数据并(可能)查看哪个偏移量存储在偏移量 60 处,然后计算偏移量处存储的数据:[0+offset[60]][120]
.
请注意,调用 return 的子例程很可能是一个值,因为 eax
可用。
关于您的评论
您认为此代码段调用 Kernel32.dll
中的函数的假设是不正确的。所有指针都指向由 MapViewOfFile
编辑的 return 缓冲区,您必须研究该特定文件的内容才能理解代码的作用。
寄存器的推送只是工作中的cdecl
调用约定。因为这是 c
代码,它在内部使用 cdecl
调用约定,要求所有参数都使用堆栈传输。
在外部它使用 stdcall
将前 3 个参数传输到寄存器中。
stdcall
和 cdecl
return 的结果都是 EAX
。