<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      hznnzh

      導(dǎo)航

      用32位匯編語言寫一個內(nèi)存補丁的例子

        今天博客就是復(fù)習(xí)一下之前看的內(nèi)容。

        現(xiàn)在網(wǎng)絡(luò)上有很多破解軟件,一個本來要錢才能用得軟件經(jīng)過大佬破解之后就變得可以不用錢了。這個破解的過程肯定是非常的辛苦,一些脫殼逆向的過程就不用多說了。而這里我只是寫了一個hello worid級別的程序,然后主要是介紹怎么用ReadProcessMemory函數(shù)和WriteProcessMemory函數(shù)來對一個進程的內(nèi)存地址空間進行讀和寫的操作。

        要對一個進程進行各種操作,那么最基本的肯定就是要先獲得進程的句柄了。獲取進程的句柄的方式有很多,可以通過CreateProcess函數(shù),也可以通過目標進程所打開的窗口的類名和標題獲得窗口的句柄,再通過窗口的句柄獲得打開該窗口的進程的ID,再通過該ID獲得進程的句柄。(這個好麻煩啊)還有一種辦法是通過快照函數(shù)獲取一個當(dāng)前系統(tǒng)的進程的快照,然后再找出目標進程。

        這上面三種方法,第一種是我們在自己的進程中用這個函數(shù)打開目標進程,然后函數(shù)會返回目標進程的句柄。也就是說那個目標進程現(xiàn)在變成了我們自己的進程的子進程。后面兩種方法都是進程已經(jīng)存在了,然后我們再去獲得句柄。但是結(jié)合我們是想模擬一個破解軟件的亞子。我們想的應(yīng)該就是打開我們的補丁程序,然后就程序自動就幫我們打好了補丁,然后再打開目標程序。如果說進程已經(jīng)存在了,那么我們再去打補丁可能就麻煩了,因為要打補丁的部分可能已經(jīng)運行過去了,并且本來就一般都是先打好了再運行的嘛。而CreateProcess函數(shù)里面的參數(shù)可以指定創(chuàng)建進程后,進程的主線程處于掛起狀態(tài),然后這個時候我們就可以對它進行打補丁的操作了。所以我們選用CreateProcess函數(shù)來創(chuàng)建目標進程。

        這里先給出這個Hello world級別的程序的源代碼

       1             .386
       2             .model    flat,stdcall
       3             option casemap:none
       4 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
       5 include        windows.inc
       6 include        user32.inc
       7 includelib    user32.lib
       8 include        kernel32.inc
       9 includelib    kernel32.lib
      10 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      11             .const
      12 szErr        db        '對不起,你使用的是盜版軟件',0
      13 szOK        db        '感謝您使用正版軟件',0
      14 szCaption    db        '謝謝',0
      15             .code
      16 start:
      17         xor        eax,eax
      18         or        eax,eax
      19         je        @F
      20         invoke    MessageBox,NULL,addr szOK,\
      21                 addr szCaption,MB_OK
      22         jmp        loc_1
      23         @@:
      24         invoke    MessageBox,NULL,addr szErr,NULL,\
      25                 MB_OK or MB_ICONSTOP
      26         loc_1:
      27         invoke    ExitProcess,NULL
      28 end        start

         該程序?qū)AX清0后判斷EAX是否是0,如果是0就顯示“使用盜版”的窗口,不是就顯示使用正版的窗口。所以這里是一定會顯示盜版窗口的。然后我們要做的就是利用之前說的那兩個讀寫進程地址空間的函數(shù)把這個進程的地址空間中的代碼改一改,讓它顯示正版窗口。

        現(xiàn)在要確定的就是改哪里的代碼。因為那兩個讀寫函數(shù)是要根據(jù)目標進程中要進行讀寫的指令的地址來使用的,所以我們還得知道代碼在目標進程中的地址。

        修改哪個地方的代碼,這個好確定(對于這個程序來說)。我們可以直接把第19行那個跳轉(zhuǎn)改為跳到下面執(zhí)行正版窗口的地方,或者是直接把這一條指令去掉,也就是用nop替換。或者用其他方法也行,這里就選擇用nop填充,因為這個比較簡單。

        那么,現(xiàn)在確定了修改哪一條代碼,剩下的就是確定要修改的代碼的地址了。所以我們將改程序反匯編一下:

       

         這個就是上面那個程序反匯編后的樣子。可以看到我們要修改的指令的地址是:00401004,并且這個指令是16位的,而nop是8位(nop的機器碼就是90h),所以我們呢要填充兩個nop。這里要注意一下,這個地址是線性地址,并不是程序真正所在的內(nèi)存地址,每次程序執(zhí)行它都是這個線性地址,所以不用擔(dān)心地址會變的問題。但是如果是DLL就不一樣了。因為一個程序,它可以裝入很多個DLL,可能這個DLL的建議裝入地址是這個,但是它裝入的時候發(fā)現(xiàn)另一個DLL已經(jīng)被裝入到這了,那它就只能改變地址了。這個時候可以可以通過查看PE文件的導(dǎo)入表來查看DLL的真正裝入位置,不過其實光查看還不行,這樣只能獲得DLL里面的函數(shù)的地址,還得在這個函數(shù)的附近掃描DLL的頭,也是一個PE文件頭,然后才能確定位置。

        我們那兩個函數(shù)用的就是線性地址,所以用反匯編顯示的地址是沒問題的。然后就介紹一下這兩個函數(shù)的用法。

        

      invoke    ReadProcessMemory,hProcess,lpBaseAddress,lpBuffer,dwSize,lpNumberOfBytesRead
      invoke   WriteProcessMemory,hProcess,lpBaseAddress,lpBuffer,dwSize,lpNumberOfBytesRead

       

        該函數(shù)讀進程的內(nèi)存。函數(shù)執(zhí)行成功返回非0值,參數(shù)定義如下:

      • hProcess:該參數(shù)指定目標進程的句柄。
      • lpBaseAddress:在目標進程中要讀寫的起始線性地址(對于ReadProcessMemory)或者在目標進程中要寫入的起始線程地址(對于WriteProcessMemory)。
      • lpBuffer:該參數(shù)指向一個緩沖區(qū),用來接收讀取的目標進程中的數(shù)據(jù)(對于ReadProcessMemory)。指向一個緩沖區(qū),緩沖區(qū)里面是要寫入的數(shù)據(jù)(對于WriteProcessMemory)。
      • dwSize:要讀或?qū)懙淖止?jié)數(shù)。
      • lpNumberOfBytesRead:該參數(shù)指向一個雙字變量,函數(shù)將返回實際讀寫的字節(jié)數(shù)在里面,可以指定為NULL如果不關(guān)心這個數(shù)據(jù)的話。

        然后要注意的就是我們在用CreateProcess函數(shù)創(chuàng)建進程的時候,要指定PROCESS_VM_READPROCESS_VM_WRITE參數(shù),這樣我們才能對進程地址空間進行讀寫。

        做完這些準備工作后,要寫一個針對上面那個簡單程序就容易多了。程序大概流程就是先用CreateProcess函數(shù)創(chuàng)建我們的目標進程,并且參數(shù)里面要指定dwFlags參數(shù)進程剛創(chuàng)建就要將主線程掛起,然后再用ReadProcessMemory函數(shù)讀取數(shù)據(jù),然后再檢測一下數(shù)據(jù)是不是我們要改的那個,這個是為了防止出現(xiàn)程序版本不一樣的情況,當(dāng)然這里這個程序不會出現(xiàn)這種問題。最后如果沒有錯誤,就用WriteProcessMemory函數(shù)將數(shù)據(jù)寫入,然后恢復(fù)進程主線程。否則就關(guān)閉進程并顯示錯誤信息。

        下面是這個簡單程序的簡單補丁程序的代碼:

       1                 .386
       2                 .model flat,stdcall
       3                 option casemap:none
       4 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
       5 ;Include
       6 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
       7 include            windows.inc 
       8 include            user32.inc
       9 includelib        user32.lib
      10 include            kernel32.inc
      11 includelib        kernel32.lib
      12 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      13 ;數(shù)據(jù)段
      14 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      15 PATCH_POSITION        equ        00401004h
      16 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      17                 .data?
      18 dbOldBytes        db        2 dup (?)            ;讀取的數(shù)據(jù)存放的緩沖區(qū)
      19 stStartUp        STARTUPINFO        <?>
      20 stProcInfo        PROCESS_INFORMATION        <?>
      21                 .const
      22 dbPatch            db        74h,15h
      23 dbPatched        db        90h,90h
      24 szExecFilename    db        'test.exe',0
      25 szErrExec        db        '無法裝載執(zhí)行文件!',0
      26 szErrVersion    db        '執(zhí)行文件的版本不正確,無法修正!',0
      27 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      28                 .code
      29 start:
      30 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      31 ;創(chuàng)建進程
      32 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      33 invoke    GetStartupInfo,addr stStartUp            ;獲取當(dāng)前進程的窗口信息
      34 invoke    CreateProcess,offset szExecFilename,NULL,NULL,NULL,\            ;創(chuàng)建進程,進程的主線程一開始就為掛起狀態(tài),防止補丁程序在修改代碼時被WINDOWS打斷
      35         NULL,NORMAL_PRIORITY_CLASS or CREATE_SUSPENDED,0,0,\
      36         offset stStartUp,offset stProcInfo
      37 .if        eax
      38 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      39 ;讀進程內(nèi)存并驗證內(nèi)容是否正確
      40 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      41         invoke    ReadProcessMemory,stProcInfo.hProcess,\                    ;讀取從程序入口開始4個字節(jié)的位置,也就是跳轉(zhuǎn)命令的地方
      42                 PATCH_POSITION,addr dbOldBytes,2,NULL
      43         .if        eax
      44                 mov        ax,word ptr dbOldBytes
      45                 .if        ax == word ptr dbPatch                            ;驗證版本信息
      46                         invoke    WriteProcessMemory,stProcInfo.hProcess,\
      47                                 PATCH_POSITION,addr dbPatched,2,NULL    ;將要修改的代碼寫入
      48                         invoke    ResumeThread,stProcInfo.hThread            ;恢復(fù)進程中的主線程
      49                 .else
      50                         invoke    TerminateProcess,stProcInfo.hProcess,-1    ;如果版本不正確則終止進程
      51                         invoke    MessageBox,NULL,addr szErrVersion,\
      52                                 NULL,MB_OK or MB_ICONSTOP
      53                 .endif
      54         .endif
      55 ;**********************************************************************************************************
      56         invoke    CloseHandle,stProcInfo.hProcess
      57         invoke    CloseHandle,stProcInfo.hThread                            ;關(guān)閉打開的進程句柄和它的線程句柄
      58 .else
      59         invoke    MessageBox,NULL,addr szErrExec,NULL,\
      60                 MB_OK or MB_ICONSTOP
      61 .endif
      62 invoke    ExitProcess,NULL
      63 
      64 end        start

         把兩個程序都編譯鏈接然后先運行目標程序:

       

        果不其然,顯示盜版信息。然后我們再直接運行補丁程序:

       

         OK,成功。但是要注意我們修改的是文件在內(nèi)存中的數(shù)據(jù),并沒有修改文件本身的數(shù)據(jù),所以下一次直接運行還是會出現(xiàn)盜版窗口。

       

      posted on 2020-03-28 20:43  hznnzh  閱讀(630)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 福利一区二区在线播放| 九九综合va免费看| 免费午夜无码片在线观看影院| 亚洲色www成人永久网址| 欧美亚洲综合成人a∨在线| 亚洲第一精品一二三区| 成年无码av片完整版| 国产视色精品亚洲一区二区| 国产成人一区二区三区视频免费| 中文字幕乱码熟女人妻水蜜桃| 亚洲の无码国产の无码步美| 国产伦精区二区三区视频| 国产精品青青在线观看爽香蕉| 99在线精品国自产拍中文字幕| 亚洲熟妇色自偷自拍另类| 香蕉eeww99国产在线观看| 崇文区| 波多野结衣久久一区二区| 国模在线视频一区二区三区| 疯狂做受xxxx高潮欧美日本| 国内自拍av在线免费| 激情动态图亚洲区域激情| 日韩全网av在线| 在线观看中文字幕国产码| 国产三级黄色的在线观看| 久国产精品韩国三级视频| 永久免费av网站可以直接看的| 亚洲精品日韩中文字幕| 午夜福利国产精品视频| 亚洲精品日韩中文字幕| 国产精品69人妻我爱绿帽子| 青青热在线精品视频免费观看| 深夜av免费在线观看| 亚洲色在线V中文字幕| 免费又黄又爽1000禁片| 激情在线一区二区三区视频| 色吊丝二区三区中文写幕| 亚洲精品一区国产| av天堂久久天堂av| 成人网站免费观看永久视频下载| 国产成人无码久久久精品一|