学习过程中记录一下

u DbgPrint l 20
nt!DbgPrint:
80528e72 8bff                        mov         edi,edi
80528e74 55                            push        ebp
80528e75 8bec                        mov         ebp,esp
80528e77 8d450c                    lea         eax,[ebp+0Ch]
80528e7a 50                            push        eax
80528e7b ff7508                    push        dword ptr [ebp+8]
80528e7e 6a00                        push        0
80528e80 6aff                        push        0FFFFFFFFh
80528e82 686c8e5280            push        offset nt!DbgSetDebugFilterState+0xc (80528e6c)
80528e87 e86afdffff            call        nt!vDbgPrintExWithPrefix (80528bf6)
80528e8c 5d                            pop         ebp
80528e8d c3                            ret
80528e8e 00cc                        add         ah,cl
80528e90 cc                             int         3
80528e91 cc                             int         3
80528e92 cc                             int         3
80528e93 cc                             int         3
nt!DbgPrintEx:
80528e94 8bff                        mov         edi,edi
80528e96 55                            push        ebp
80528e97 8bec                        mov         ebp,esp
80528e99 8d4514                    lea         eax,[ebp+14h]
80528e9c 50                            push        eax
80528e9d ff7510                    push        dword ptr [ebp+10h]
80528ea0 ff750c                    push        dword ptr [ebp+0Ch]
80528ea3 ff7508                    push        dword ptr [ebp+8]
80528ea6 688e8e5280            push        offset nt!DbgPrint+0x1c (80528e8e)
80528eab e846fdffff            call        nt!vDbgPrintExWithPrefix (80528bf6)
最近遇到一个问题,想要确定某一函数的大小,这在IDA的输出表种可以很清楚的看到。
那么怎么才能确定某一函数的大小呢?
求助以后,假如两个函数是相邻的,那么可以通过 FUN2() 开头- FUN1()开头
得到函数的大小。
比如WINDBG中显示的:如上图。
 
记得在搜索导出表的时候,是一个FOR循环的过程,那这个循环过程是不是就是相邻的呢?
 
还记得《软件加密技术内幕》上面有牛人的分析导出表的过程,那么拿来看看吧。
 

  pwOrds        = (PWORD)RvaToPtr(pNtH, stMapFile.ImageBase,pExportDir->AddressOfNameOrdinals);
  pdwRvas     = (PDWORD)RvaToPtr(pNtH, stMapFile.ImageBase,pExportDir->AddressOfFunctions);
  pdwNames    = (PDWORD)RvaToPtr(pNtH, stMapFile.ImageBase,pExportDir->AddressOfNames);

   if(!pdwRvas)
     return;
    
  hList=GetDlgItem(hDlg,IDC_EXPORT_LIST);
  SendMessage(hList,LVM_SETEXTENDEDLISTVIEWSTYLE,0,(LPARAM)LVS_EX_FULLROWSELECT);
    
    
  iNumOfName=pExportDir->NumberOfNames;

   for( i=0;i<pExportDir->NumberOfFunctions;i++)
  {
     if(*pdwRvas)
    {        
       for( j=0;j<iNumOfName;j++)
      {
         if(i==pwOrds[j])
        {    
          bIsByName=TRUE;
          szFuncName=( char*)RvaToPtr(pNtH,stMapFile.ImageBase,pdwNames[j]);
           break;
        }
        
        bIsByName=FALSE;
      }
                    
pwOrds 是输出序号,pdwRvas 是函数的RVA(这个值加上导出该函数模块的加载地址就可以得到函数的输出地址),pdwNames就是平时我们看到的函数名称了。
 
for( i=0;i<pExportDir->NumberOfFunctions;i++)
这一句就是我们平时分析导出函数的地址时候最常用的一句了。
那么?这是不是就是分析的相邻的两个函数呢?
 
 
可以看到这个表输出的RVA并不是像我原先想象的那样,是FUN1()的RVA +   SIZEOF( FUN1() )就是第二个函数FUN2()的RVA。
 
那我们通过什么方法来得到呢?
在与qq聊友的对话中,突发灵感,一般函数的特征都是末尾是RET,开头是
PUSH EBP;
MOV  EBP,ESP;
。。。
这样的话,我们完全可以把上面的东西作为特征码。只要两个函数之间没有那个特征,那么这两个函数就是我所谓的两个“相邻的函数”。
 
但是貌似微软的结尾函数有些是不一样的,有些是0X90.有的是以INT3结尾的,那么这部就复杂了?
哦,对了,函数的开头是
mov     edi, edi
push    ebp
mov     ebp, esp
这在内核函数还是普通的函数中都是适用的。那么,思路就有了,我们找到了2个含有上述特征码的函数后(证明这2个函数是我所谓的相邻的函数),再分析这两个函数的开头特征,只要这两个函数RVA相减就得到了这个函数的大小了。当然前提是这两个函数中间不含有多余的无用代码。
 
不过貌似R3下的函数都有一个特征哎。就是那几个nop了。
不知道是不是通用。
 
 
IDA是如何做到的呢?
 
继续思考中。。。
 
顺便加一个VC下如何得到函数大小的帖子
[url]http://bbs.pediy.com/showthread.php?t=22607[/url]
 

你可能感兴趣的:(c,职场,休闲)