學習過程中記錄一下

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下如何得到函數大小的帖子
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章