• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            小默

            [zz]失業的娛樂-IDA逆向工程入門(三)

            【文章標題】: 失業的娛樂-IDA逆向工程入門(三)-匯編程序(2)
            【文章作者】: layper
            【作者郵箱】: layper@yahoo.comcn
            【作者主頁】: http://blog.csdn.net/layper/
            【下載地址】: 自己搜索下載
            【編寫語言】: asm
            【使用工具】: IDA\reshack\radasm\
            【作者聲明】: 只是感興趣,沒有其他目的。失誤之處敬請諸位大俠賜教!
            --------------------------------------------------------------------------------
            【詳細過程】
              多謝大家的支持,特別是fly還關心我的工作問題,無已回報,只能繼續寫些小文供大家批評了!!!
              
              上一篇我們所逆的是非常簡單的win32匯編,總共才兩個api函數,一個消息框和ExitProcess函數,這篇我們就涉及一個真正的窗口
              程序firstwindows,我學匯編是看了羅云彬的《windows環境下匯編語言程序設計》才入門的,我直接拿里面的例子來講吧,如果作
              者覺得不合適,我會刪去的!!!!!
              
              順便講一下學習逆向工程的方法,這個跟學脫殼方法類似,你先用一種語言寫一個程序(剛開始比較簡單的),編譯后用IDA或者
              其他工具反匯編,觀察源代碼和反匯編代碼有什么異同,想辦法在逆向代碼中逐漸靠近源代碼,最后再把他整理到編譯工具中不
              斷編譯,在編譯器中看那里出錯,逐步修改,直至成功,最后總結經驗,這樣就會逐步提高了.
              
              限于篇幅,我只把完整源碼貼出來,未修改的反匯編在壓縮包內的1.asm,請自行查看
              firstwindows源碼
              
              ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
              ; Sample code for < Win32ASM Programming >
              ; by 羅云彬, http://asm.yeah.net
              ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
              ; FirstWindow.asm
              ; 窗口程序的模板代碼
              ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
              ; 使用 nmake 或下列命令進行編譯和鏈接:
              ; ml /c /coff FirstWindow.asm
              ; Link /subsystem:windows FirstWindow.obj
              ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                  .386
                  .model flat,stdcall
                  option casemap:none
              ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
              ; Include 文件定義
              ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
              include    windows.inc
              include    gdi32.inc
              includelib  gdi32.lib
              include    user32.inc
              includelib  user32.lib
              include    kernel32.inc
              includelib  kernel32.lib
              ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
              ; 數據段
              ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                  .data?
              
              hInstance  dd    ?
              hWinMain  dd    ?
              
                  .const
              
              szClassName  db  'MyClass',0
              szCaptionMain  db  'My first Window !',0
              szText    db  'Win32 Assembly, Simple and powerful !',0
              ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
              ; 代碼段
              ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                  .code
              ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
              ; 窗口過程
              ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
              _ProcWinMain  proc  uses ebx edi esi,hWnd,uMsg,wParam,lParam
                  local  @stPs:PAINTSTRUCT
                  local  @stRect:RECT
                  local  @hDc
              
                  mov  eax,uMsg
              ;********************************************************************
                  .if  eax ==  WM_PAINT
                    invoke  BeginPaint,hWnd,addr @stPs
                    mov  @hDc,eax
              
                    invoke  GetClientRect,hWnd,addr @stRect
                    invoke  DrawText,@hDc,addr szText,-1,\
                      addr @stRect,\
                      DT_SINGLELINE or DT_CENTER or DT_VCENTER
              
                    invoke  EndPaint,hWnd,addr @stPs
              ;********************************************************************
                  .elseif  eax ==  WM_CLOSE
                    invoke  DestroyWindow,hWinMain
                    invoke  PostQuitMessage,NULL
              ;********************************************************************
                  .else
                    invoke  DefWindowProc,hWnd,uMsg,wParam,lParam
                    ret
                  .endif
              ;********************************************************************
                  xor  eax,eax
                  ret
              
              _ProcWinMain  endp
              ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
              _WinMain  proc
                  local  @stWndClass:WNDCLASSEX
                  local  @stMsg:MSG
              
                  invoke  GetModuleHandle,NULL
                  mov  hInstance,eax
                  invoke  RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
              ;********************************************************************
              ; 注冊窗口類
              ;********************************************************************
                  invoke  LoadCursor,0,IDC_ARROW
                  mov  @stWndClass.hCursor,eax
                  push  hInstance
                  pop  @stWndClass.hInstance
                  mov  @stWndClass.cbSize,sizeof WNDCLASSEX
                  mov  @stWndClass.style,CS_HREDRAW or CS_VREDRAW
                  mov  @stWndClass.lpfnWndProc,offset _ProcWinMain
                  mov  @stWndClass.hbrBackground,COLOR_WINDOW + 1
                  mov  @stWndClass.lpszClassName,offset szClassName
                  invoke  RegisterClassEx,addr @stWndClass
              ;********************************************************************
              ; 建立并顯示窗口
              ;********************************************************************
                  invoke  CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,\
                    WS_OVERLAPPEDWINDOW,\
                    100,100,600,400,\
                    NULL,NULL,hInstance,NULL
                  mov  hWinMain,eax
                  invoke  ShowWindow,hWinMain,SW_SHOWNORMAL
                  invoke  UpdateWindow,hWinMain
              ;********************************************************************
              ; 消息循環
              ;********************************************************************
                  .while  TRUE
                    invoke  GetMessage,addr @stMsg,NULL,0,0
                    .break  .if eax  == 0
                    invoke  TranslateMessage,addr @stMsg
                    invoke  DispatchMessage,addr @stMsg
                  .endw
                  ret
              
              _WinMain  endp
              ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
              start:
                  call  _WinMain
                  invoke  ExitProcess,NULL
              ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                  end  start
              
              在radasm編譯通過.
              
              用IAD反匯編載入完成后,點擊文件-創建文件-創建asm文件就得到未經修改的反匯編后得到的1.asm文件(有點繞口:)),直接用
              radasm打開,在radasm中ctrl+f5構建并運行看看結果怎樣,呵呵,出錯了.

            因為一步一步來講比較長,我先把操作過程寫下來,在慢慢解釋,1.asm修改如下:
            (一)增加模式定義\options語句\還原include語句
                  .686p
                  .mmx
                  .model flat,stdcall
                  option casemap:none
              include WINDOWS.INC
              include kernel32.inc
              includelib kernel32.lib
              include user32.inc
              includelib user32.lib
            (二)刪除結構MSG\POINT\PAINTSTRUCT\RECT,并把余下的結構移動到  includelib user32.lib之后,即第一步之后,
            然后做如下修改:
            tagMSG    struc ;  (sizeof=0x1C, standard type)
            hwnd    dd ?      ; offset
            message    dd ?
            wParam    dd ?
            lParam    dd ?
            time    dd ?
            pt    POINT ?    ;這里修改為pt    POINT <>
            tagMSG    ends

            tagPAINTSTRUCT  struc ;  (sizeof=0x40, standard type)
            hdc    dd ?      ; offset
            fErase    dd ?
            rcPaint    RECT ?      ;這里修改為rcPaint    RECT <>
            fRestore  dd ?
            fIncUpdate  dd ?
            rgbReserved  db 32 dup(?)
            tagPAINTSTRUCT  ends
            (三)對函數的局部變量進行修改
            一共三個函數start\sub_401000和sub_401089,修改如下
            sub_401089:
            sub_401089  proc near    ; CODE XREF: startp

            Msg    = MSG ptr -4Ch
            var_30    = WNDCLASSEXA ptr -30h
            修改為:
            sub_401089  proc near    ; CODE XREF: startp

                LOCAL Msg:MSG 
                LOCAL var_30:WNDCLASSEXA 



            sub_401000:

            sub_401000  proc near    ; DATA XREF: sub_401089+43o

            hDC    = dword  ptr -54h
            Rect    = tagRECT ptr -50h
            Paint    = PAINTSTRUCT ptr -40h
            hWnd    = dword  ptr  8
            Msg    = dword  ptr  0Ch
            wParam    = dword  ptr  10h
            lParam    = dword  ptr  14h

            修改為:
            sub_401000  proc uses ebx edi esi ,hWnd,Msg,wParam,lParam    ; DATA XREF: sub_401089+43o

                LOCAL hDC
                LOCAL Rect:tagRECT
                LOCAL Paint:PAINTSTRUCT


            (四)_text段修改
            刪除
            在_text段前增加.code
            _text    segment  para public 'CODE' use32
                assume cs:_text
                ;org 401000h
                assume es:nothing, ss:nothing, ds:_data, fs:nothing, gs:nothing

            _text    ends
            注意:中間的代碼不要刪除!!!

            (五)刪除align 40h

            (六)移動修改_data段
            在.code前增加.data,并且把_data段移動到這里

            _data    segment  para public 'DATA' use32
                assume cs:_data
                ;org 403000h
            和          ; sub_401089+A6r
            _data    ends
            刪除
            注意:中間的代碼不要刪除!!!

            (七)修改sub_401000的hWnd,只要出現有的都修改為hWnd1.

            (八)刪除_idata段

            (九)
            把函數含有[ebp+變量]的代碼全部修改為變量
            sub_401089的代碼
            [ebp+var_30] 改為  var_30
            [ebp+var_30.hCursor]  改為  var_30.hCursor
            [ebp+var_30.hInstance]  改為  var_30.hInstance
            [ebp+var_30.cbSize]  改為  var_30.cbSize
            [ebp+var_30.style]  改為  var_30.style
            [ebp+var_30.lpfnWndProc]  改為  var_30.lpfnWndProc
            [ebp+var_30.hbrBackground]  改為  var_30.hbrBackground
            [ebp+var_30.lpszClassName]  改為  var_30.lpszClassName
            [ebp+Msg]    改為  Msg

            sub_401000的代碼
            [ebp+hDC]    改為  hDC
            [ebp+Rect]    改為  Rect
            [ebp+Paint]    改為  Paint
            [ebp+hWnd1]    改為  hWnd1
            [ebp+Msg]    改為  Msg
            [ebp+wParam]    改為  wParam
            [ebp+lParam]    改為  lParam

            (十)刪掉函數多余的開頭
            sub_401089處:
            sub_401089  proc near    ; CODE XREF: startp

                LOCAL Msg:MSG 
                LOCAL var_30:WNDCLASSEXA 

                push  ebp    ;刪掉
                mov  ebp, esp  刪掉
                add  esp, 0FFFFFFB4h  ;刪掉

            sub_401000處:
            sub_401000  proc near uses ebx edi esi ,hWnd1,Msg,wParam,lParam    ; DATA XREF: sub_401089+43o

                LOCAL hDC
                LOCAL Rect:tagRECT
                LOCAL Paint:PAINTSTRUCT


                push  ebp  ;刪掉
                mov  ebp, esp  ;刪掉
                add  esp, 0FFFFFFACh  ;刪掉
                push  ebx    ;刪掉
                push  edi    ;刪掉
                push  esi    ;刪掉


            --------------------------------------------------------------------------------
            【經驗總結】
             其實只要你把反編譯的代碼按照radasm的提示一步一步修改就可以了.
            解釋:
            (一)
            這一步我在上篇已經解釋的比較明白了.因為我們匯編開頭就是那么幾句代碼.
            include語句加回去這個是因為我們編譯的是匯編程序,這樣肯定要用到庫.如果IDA使用生成的_data段
            就非常容易出錯.畢竟它只是"識別"而不是源碼!!!!!!!

            (二)
             (1)刪除結構體MSG\POINT\PAINTSTRUCT\RECT
            我們進行了第一步操作后,用radasm進行構建,就會提示我們
            D:\masm32\Include\WINDOWS.INC(7873) : error A2163:  : POINT
            D:\masm32\Include\WINDOWS.INC(7874) : error A2163:  : POINT
            D:\masm32\Include\WINDOWS.INC(8841) : error A2163:  : MSG
            D:\masm32\Include\WINDOWS.INC(8842) : error A2163:  : MSG
            D:\masm32\Include\WINDOWS.INC(8843) : error A2163:  : MSG
            D:\masm32\Include\WINDOWS.INC(8844) : error A2163:  : MSG
            D:\masm32\Include\WINDOWS.INC(8845) : error A2163:  : MSG
            D:\masm32\Include\WINDOWS.INC(8846) : error A2163:  : MSG
            D:\masm32\Include\WINDOWS.INC(8846) : fatal error A1016: 

            構建時發生錯誤.
            總共編譯時間 271 毫秒

            這個這個意思說我們的庫文件出錯,這個可能嗎?當然也有可能,但我想你首先應該想到是你的反匯編代碼錯.
            先查詢一下windows.inc"出錯"的到底是什么
            POINT STRUCT
              x  DWORD ?  ;7873行
              y  DWORD ?  ;7874行
            POINT ENDS

            MSG STRUCT
              hwnd      DWORD      ?  ;8841
              message   DWORD      ?  ;8842
              wParam    DWORD      ?  ;8843
              lParam    DWORD      ?  ;8844
              time      DWORD      ?  ;8845
              pt        POINT      <>  ;8846
            MSG ENDS

            呵呵,你再看看反匯編代碼開頭
            MSG    struc ;  (sizeof=0x1C, standard type)
            hwnd    dd ?      ; offset
            message    dd ?
            wParam    dd ?
            lParam    dd ?
            time    dd ?
            pt    POINT ?
            MSG    ends

            ; ---------------------------------------------------------------------------

            POINT    struc ;  (sizeof=0x8, standard type)
            x    dd ?
            y    dd ?
            POINT    ends
            明白怎么是這樣了吧?我們反匯編代碼重復定義了結構msg,point所以要把他們刪除.同理PAINTSTRUCT\RECT也刪除了.
            (2)移動剩余結構到include語句后.
            這一步我是為了省事,剩余三個結構
            tagMSG    struc ;  (sizeof=0x1C, standard type)
            hwnd    dd ?      ; offset
            message    dd ?
            wParam    dd ?
            lParam    dd ?
            time    dd ?
            pt    POINT ?
            tagMSG    ends
            ; ---------------------------------------------------------------------------
            WNDCLASSEXA  struc ;  (sizeof=0x30, standard type)
            cbSize    dd ?
            style    dd ?
            lpfnWndProc  dd ?      ; offset
            cbClsExtra  dd ?
            cbWndExtra  dd ?
            hInstance  dd ?      ; offset
            hIcon    dd ?      ; offset
            hCursor    dd ?      ; offset
            hbrBackground  dd ?      ; offset
            lpszMenuName  dd ?      ; offset
            lpszClassName  dd ?      ; offset
            hIconSm    dd ?      ; offset
            WNDCLASSEXA  ends
            ; ---------------------------------------------------------------------------
            tagRECT    struc ;  (sizeof=0x10, standard type)
            left    dd ?
            top    dd ?
            right    dd ?
            bottom    dd ?
            tagRECT    ends
            ; ---------------------------------------------------------------------------
            tagPAINTSTRUCT  struc ;  (sizeof=0x40, standard type)
            hdc    dd ?      ; offset
            fErase    dd ?
            rcPaint    RECT ?
            fRestore  dd ?
            fIncUpdate  dd ?
            rgbReserved  db 32 dup(?)
            tagPAINTSTRUCT  ends
            其中tagMSG和tagPAINTSTRUCT結構分別用到了POINT結構和RECT結構,剛才我們刪了,只有windows.inc中有
            所以直接把他們剪切到這里省去出錯的機會.
            (3)修改結構
            tagMSG結構和tagPAINTSTRUCT結構修改,我是參照windows.inc結構定義方法.結構中用結構<> :)
            這個不一定完全正確,想研究這方面多閱讀.inc文件

            (三)函數修改
            在反匯編代碼中只要出現proc的,到現在為止我都看成是函數!!!
            IDA反匯編都它的函數都變成這個樣子
            sub_401000  proc near    ; DATA XREF: sub_401089+43o

            hDC    = dword  ptr -54h  ;注意這里是減(-)
            Rect    = tagRECT ptr -50h
            Paint    = PAINTSTRUCT ptr -40h
            hWnd    = dword  ptr  8    ;這里其實是加(+)
            Msg    = dword  ptr  0Ch
            wParam    = dword  ptr  10h
            lParam    = dword  ptr  14h

                push  ebp
                mov  ebp, esp
                add  esp, 0FFFFFFACh
                push  ebx
                push  edi
                push  esi
                mov  eax, [ebp+Msg]
            這里就會出現一個問題.我們先前又刪結構又改結構,而這里又用到結構,不修改編譯也會出錯的.
            我們改成比較正規的win32匯編程序格式.
            剛才我提示加減的地方,總結一條規律給大家:
            函數開頭 xx = 結構 - xxh 這個就是函數的局部變量,可用local xx:結構替換.
            函數開頭 xx = dword  ptr xxh 這個是函數的參數,函數可改為
            函數名 proc xx

            (四)_text段修改
            代碼段
            _text    segment  para public 'CODE' use32
                assume cs:_text
                ;org 401000h
                assume es:nothing, ss:nothing, ds:_data, fs:nothing, gs:nothing

            _text    ends
            IDA這種段寫法有很大的弊端,也是引起我們修改后的代碼編譯不通過的一個很重要原因.(具體我還說不上來,我還很菜)

            (五)刪除align 40h
            align是反匯編代碼不通過編譯的一種常見錯誤.

            (六)移動修改_data段
            一般來說_data段是我們的數據段,一般我們放在前面.(呵呵,代碼順序也很重要)

            (七)在數據段中
            hWnd    dd ?      ; DATA XREF: sub_401000+54r
                      ; sub_401089+94w sub_401089+9Br
                      ; sub_401089+A6r
            提示hWnd是函數sub_401089的,并不是sub_401000,所以要重命名他們.

            (八)刪除_idata段
            include語句已經有了函數定義,再保留這里就會出錯.

            (九)
            把函數含有[ebp+變量]的代碼全部修改為變量
            [ebp+]這個是編譯器加上去的,我們直接用的話,編譯后會變成[ebp+ebp+變量],容易出錯.

            (十)刪掉函數多余的開頭
            反匯編代碼中,編譯器為你加上象這樣的代碼
                push  ebp
                mov  ebp, esp
                add  esp, 0FFFFFFB4h
            如果你直接編譯的話代碼就變成了:
                push  ebp
                mov  ebp, esp
                add  esp, 0FFFFFFB4h
                push  ebp
                mov  ebp, esp
                add  esp, 0FFFFFFB4h
            重新編譯也容易出錯,所以要刪去.

            同理,要注意函數結束地方看看是否要刪去.

            (十一)
            這里說一點跟上一篇不同的是沒有刪除_rdata,因為這里有我們程序要的數據,所以沒刪除.如
            果你還想優化自己弄了!!!

            呵呵,終于弄完這篇了,把它整理好花了好大工夫.錯誤難免,請多包涵!!!!

            --------------------------------------------------------------------------------
            【版權聲明】: 本文原創于看雪技術論壇, 轉載請注明作者并保持文章的完整, 謝謝!

                                                                   2007年03月04日 12:21:20

            posted on 2009-12-25 12:10 小默 閱讀(660) 評論(0)  編輯 收藏 引用 所屬分類: Tools

            導航

            統計

            留言簿(13)

            隨筆分類(287)

            隨筆檔案(289)

            漏洞

            搜索

            積分與排名

            最新評論

            閱讀排行榜

            久久精品国产亚洲av日韩| 久久国产福利免费| 久久久无码精品亚洲日韩蜜臀浪潮| 青春久久| 国产一区二区三区久久精品| 亚洲精品高清国产一久久| 亚洲欧美一级久久精品| 精品国产一区二区三区久久| 青青草国产精品久久久久| 人妻少妇久久中文字幕| 久久综合一区二区无码| 91超碰碰碰碰久久久久久综合| 精品久久久久一区二区三区| 国内精品人妻无码久久久影院导航| 欧美色综合久久久久久| 久久综合香蕉国产蜜臀AV| 国内精品久久久久久久久| 国产香蕉久久精品综合网| 亚洲精品高清一二区久久| 91精品国产乱码久久久久久 | 亚洲国产精品无码久久久蜜芽| 激情五月综合综合久久69| 久久99精品久久久久婷婷| 久久亚洲精品人成综合网| 国内精品伊人久久久久妇| 国内精品久久久久久久久电影网| 国产精品一区二区久久国产| 影音先锋女人AV鲁色资源网久久| 久久精品中文字幕第23页| 久久久黄色大片| 亚洲日本久久久午夜精品| 国产精品免费久久| 综合久久一区二区三区 | 97精品伊人久久大香线蕉app| 久久精品国产久精国产果冻传媒| 开心久久婷婷综合中文字幕| 精品国产青草久久久久福利| 久久国产热这里只有精品| 久久久久亚洲AV无码专区桃色| 久久99精品久久久久久齐齐| 亚洲国产精品一区二区三区久久|