JefferyZhou

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

The _ReturnAddress intrinsic provides the address of the instruction in the calling function that will be executed after control returns to the caller.

返回调用当前函数的,下一个控制权获得者的指令.

如下列伪代码:

function A()

    addr =  _ReturnAddress() 

    return addr

end

function B()

     i = 4

    addr = A()

     i = 3 // addr == &(i = 3)

end

通常辅助另外一个函数,就获得一个Model的名字。

GetModuleNameByAddr((DWORD)pRetAddr, szModuleName, _countof(szModuleName));

{

BOOL XX::GetModuleNameByAddr(DWORD dwAddr, char *szName, UINT cch)

{

typedef struct _PEB_LDR_DATA {                          // Size = 0x24

ULONG Length;                             // 00

BOOLEAN Initialized;                        // 04

PVOID SsHandle;                           // 08

LIST_ENTRY InLoadOrderModuleList;              // 0C

LIST_ENTRY InMemoryOrderModuleList;            // 14

LIST_ENTRY InInitializationOrderModuleList;    // 1C

//  void *          EntryInProgress;                // 24

      } PEB_LDR_DATA, *PPEB_LDR_DATA;

szName[0] = 0;

void  *PEB = NULL,

                  *Flink = NULL,

                  *p = NULL;        

PEB_LDR_DATA *pLdr = NULL;

__asm

      {

mov edx,fs:[0x30]

mov PEB,edx

      }

pLdr = *(PEB_LDR_DATA **)((char *)PEB + 0x0c);

Flink = &pLdr->InLoadOrderModuleList;

p = pLdr->InLoadOrderModuleList.Flink;

__try

      {

do

            {

void *pBaseAddress = *(void **)((char *)p + 0x18);

assert(pBaseAddress && ((DWORD)pBaseAddress & 0xFFFF) == 0);

if (!pBaseAddress)

break;

wchar_t *lpwszFullName = *( ( wchar_t ** )( ( unsigned char * )p + 0x28 ) );

DWORD dwImageSize = *( ( DWORD * )( ( unsigned char * )p + 0x20 ) );

if (dwAddr >= (DWORD)pBaseAddress && dwAddr < (DWORD)pBaseAddress + dwImageSize)

                  {

wchar_t *lpwszName = lpwszFullName;

for (int i = 0; lpwszFullName[i] != 0; i++)

                        {

if (lpwszFullName[i] == L'\\')

lpwszName = lpwszFullName + i + 1;

                        }

                        ::WideCharToMultiByte(CP_ACP, 0, lpwszName, -1, szName, cch, NULL, NULL);

break;

                  }

p = *( ( void ** )p);

            } while ( Flink != p );

      }

__except(EXCEPTION_EXECUTE_HANDLER)

      {

assert(0);

      }

return szName[0] != 0;

}

}

_ReturnAddress 需要做内联属性,所以在调用前,需要

#pragma intrinsic(_ReturnAddress)

这里有个主意事项,内联函数和_ReturnAddress的返回值,如果把一个函数内联,那么_ReturnAddress就会相应的提升到上一个回溯堆栈中,

也就意味着返回地址是上一级的调用返回地址。

posted on 2012-09-24 16:55  JefferyZhou  阅读(2354)  评论(0编辑  收藏  举报