1. 程式人生 > >Windows記憶體詳解(四)OD記憶體斷點初步分析

Windows記憶體詳解(四)OD記憶體斷點初步分析

記憶體斷點原理:

       記憶體斷點原理,通過將記憶體斷點所在記憶體頁的屬性修改為記憶體斷點屬性(non-access or non-writable),程式執行時,對目標記憶體頁中所有資料的訪問或寫,都會丟擲異常,OD通過截獲此異常,然後對比,儲存在某一記憶體的記憶體斷點資訊表的地址,判斷是否匹配記憶體斷點地址範圍,匹配則中斷程式執行,否則,繼續執行。

IDA靜態分析:

本例利用IDA和OD動靜結合,分析OD記憶體斷點基本流程,以及記憶體斷點儲存在哪兒段記憶體地址。

首先將OD丟進IDA中,在程式函式列表中搜索breakpoint字串,如圖:


我們僅分析記憶體斷點,通過function name 可知:_setmembreakpoint是我們需要分析的函式。跳到該函式分析,入口點部分截圖:


可知,該函式有3個引數,通過F5(hexray),其反編譯虛擬碼:

  1. signedint __cdecl Setmembreakpoint(__int16 a1, unsigned int a2, int a3)  
  2. {  
  3.   _DWORD *v3; // [email protected]
  4.   signedint result; // [email protected]
  5.   if ( !dword_4D8138 && VersionInformation.dwPlatformId != 2 )  
  6.   {  
  7.     v3 = Findmemory(a2);  
  8.     if ( a2 < 0x80000000 )     //判斷記憶體斷點地址是否在使用者記憶體中(0x800000~0xffffffff屬於系統核心記憶體區域)
  9.     {  
  10.       if ( v3 && *((_BYTE *)v3 + 11) & 1 )   //判斷記憶體斷點是否在資源記憶體區域
  11.       {  
  12.         if ( MessageBoxA(  
  13.                hWnd,  
  14.                "You are going to set memory breakpoint on resource. This breakpoint, when hit within system DLL, may freeze Windows or cause system crash. Do you really want to set this breakpoint?"
    ,  
  15.                "Memory breakpoint on resource",  
  16.                0x14u) != 6 )  
  17.           return -1;  
  18.       }  
  19.       else
  20.       {  
  21.         if ( v3 && *((_BYTE *)v3 + 11) & 4 )    //判斷記憶體斷點地址是否在堆疊記憶體區域
  22.         {  
  23.           MessageBoxA(  
  24.             hWnd,  
  25.             "You are going to set memory breakpoint on stack. This doesn't work on Win95-based operating systems.",  
  26.             "Memory breakpoint on stack",  
  27.             0x10u);  
  28.           return -1;  
  29.         }  
  30.       }  
  31.     }  
  32.     else
  33.     {  
  34.       if ( MessageBoxA(  
  35.              hWnd,  
  36.              "You are going to set memory breakpoint in system area. This breakpoint may freeze Windows or cause system crash. Do you really want to set this breakpoint?",  
  37.              "Memory breakpoint in system area",  
  38.              0x14u) != 6 )  
  39.         return -1;  
  40.     }  
  41.   }  
  42.   if ( sub_418E24() )  
  43.   {  
  44.     result = -1;  
  45.   }  
  46.   else
  47.   {  
  48.     dword_4D813C = a2;  
  49.     dword_4D8140 = a3;  
  50.     dword_4D8144 = a2 & 0xFFFFF000;  
  51.     dword_4D8148 = (a3 + a2 + 4095) & 0xFFFFF000;  
  52.     dword_4D8138 = (HIBYTE(a1) & 0x10) != 0;  
  53.     dword_4D8D5C = 1;  
  54.     if ( a1 & 3 && a3 )  
  55.     {  
  56.       if ( (a1 & 3) == 2 )  
  57.         dword_4D814C = 32;  
  58.       else
  59.         dword_4D814C = 1;  
  60.       if ( dword_4D5A5C == 3 )  
  61.         sub_419034();  
  62.       result = 0;  
  63.     }  
  64.     else
  65.     {  
  66.       result = 0;  
  67.     }  
  68.   }  
  69.   return result;  
  70. }  

OD除錯OD動態分析:

我們通過OD來除錯OD,分析setmembreakpoint函式的流程。

將OD丟進OD中,並在setmembreakpoint入口地址下斷點(F2),並執行被除錯的OD。然後在被除錯的OD程式中載入除錯一個任意程式,並在某一地址下記憶體訪問斷點,如圖(被除錯的od程式中,在紅線0x401377處下了記憶體斷點):


下完該記憶體斷點,除錯程式OD立即捕獲,並中斷在setmembreakpoint的入口地址,然後我們通過單步,檢視該函式的三個引數分別是神馬:


發現esi中的值即我們在被除錯程式中所下的記憶體斷點地址,edi為記憶體斷點的位元組長度(0x401377處指令為6bytes)。ebx值其實是記憶體斷點的屬性(訪問:0x00000003,寫:0x00000002),這裡我們之前下的是記憶體訪問斷點,所以ebx:0x00000003。

繼續單步執行,在0x4192fb處跳轉到0x41938d。先不管這裡為什麼會調轉。繼續單步,發現之後的彙編操作將我們所下的記憶體斷點資訊儲存到了某段記憶體中,如圖:


當前eax=0x401377,即我們的記憶體斷點地址。

分析彙編:
  1. 004193A2  |.  A3 3C814D00   mov     dword ptr [4D813C], eax   //將記憶體斷點地址儲存到0x4d813c處         
  2. 004193A7  |.  8BC8          mov     ecx, eax      //ecx=eax=0x401377 記憶體斷點地址  
  3. 004193A9  |.  03C2          add     eax, edx      //edx為記憶體斷點位元組長度,這裡是取記憶體斷點結束地址,本例中,eax=0x401377+6=0x40137d  
  4. 004193AB  |.  81E1 00F0FFFF and     ecx, FFFFF000   //相當於去該記憶體地址所在的記憶體頁起始地址   ecx=0x401000  
  5. 004193B1  |.  05 FF0F0000   add     eax, 0FFF      //將記憶體斷點結束地址加上了一個記憶體頁大小  
  6. 004193B6  |.  8915 40814D00 mov     dword ptr [4D8140], edx  //將記憶體斷點長度儲存到0x4d8140  
  7. 004193BC  |.  25 00F0FFFF   and     eax, FFFFF000   //取該記憶體地址所在的記憶體頁地址  
  8. 004193C1  |.  890D 44814D00 mov     dword ptr [4D8144], ecx   //將記憶體斷點坐在記憶體也的起始地址儲存到0x4d8144處  
  9. 004193C7  |.  F6C7 10       test    bh, 10    //設定zf屬性,執行後,zf=1  
  10. 004193CA  |.  A3 48814D00   mov     dword ptr [4D8148], eax   //本例中eax=402000  
  11. 004193CF  |.  0F95C0        setne   al      //if zf=1 then al=0, if zf=0 then al=1  
  12. 004193D2  |.  83E0 01       and     eax, 1        //之後 eax=0x00000000  
  13. 004193D5  |.  83E3 03       and     ebx, 3        //ebx之前儲存的是記憶體斷點屬性(訪問or 寫)  
  14. 004193D8  |.  A3 38814D00   mov     dword ptr [4D8138], eax    //儲存這個不知道有何用途  
  15. 004193DD  |.  C705 5C8D4D00>mov     dword ptr [4D8D5C], 1    
  16. 004193E7  |.  85DB          test    ebx, ebx  
  17. 004193E9  |.  74 04         je      short 004193EF  
  18. 004193EB  |.  85FF          test    edi, edi       //edi存的是記憶體斷點位元組長度  
  19. 004193ED  |.  75 04         jnz     short 004193F3   //跳轉成功  
  20. 004193EF  |>  33C0          xor     eax, eax  
  21. 004193F1  |.  EB 2B         jmp     short 0041941E  
  22. 004193F3  |>  83FB 02       cmp     ebx, 2           //ebx與2 比較,判斷是否是記憶體寫屬性  
  23. 004193F6  |.  75 0C         jnz     short 00419404     //不是則跳轉到0x419404(訪問屬性)  
  24. 004193F8  |.  C705 4C814D00>mov     dword ptr [4D814C], 20   //記憶體寫屬性,則將0x20儲存在0x4d814c  
  25. 00419402  |.  EB 0A         jmp     short 0041940E  
  26. 00419404  |>  C705 4C814D00>mov     dword ptr [4D814C], 1    //記憶體訪問屬性,將0x01儲存在0x4d814c  
  27. 0041940E  |>  833D 5C5A4D00>cmp     dword ptr [4D5A5C], 3  
  28. 00419415  |.  75 05         jnz     short 0041941C  
  29. 00419417  |.  E8 18FCFFFF   call    00419034  
  30. 0041941C  |>  33C0          xor     eax, eax  
  31. 0041941E  |>  5F            pop     edi  
  32. 0041941F  |.  5E            pop     esi  
  33. 00419420  |.  5B            pop     ebx  
  34. 00419421  |.  5D            pop     ebp  
  35. 00419422  \.  C3            retn  

通過對上面的彙編程式碼的分析,我們基本上可以定位記憶體斷點資訊的儲存地址:0x4d8138~0x4d814f ,本例如圖:


0x4d8138~0x40813b:0x00000000 未知

0x4d813c~0x4d813f: 0x00401377 記憶體斷點起始地址

0x4d8140~0x4d8143: 0x00000006 記憶體斷點長度

0x4d8144~0x4d8147: 0x00401000 記憶體斷點地址所在的記憶體頁起始地址

0x4d8148~0x4d814b: 0x00402000 記憶體斷點尾部地址+記憶體也大小地址後,所在的記憶體頁起始地址(這裡有所疑問,為什麼要加上0xfff,而不是直接取記憶體斷點尾部地址所在的記憶體頁起始地址,本例中,應該也是0x401000)。

0x4d814c~0x4d814f:0x00000001 記憶體斷點屬性(訪問:0x00000001,寫:0x00000020,與ebx區分開)

對該段記憶體的賦值其實在初始化一個結構體,該結構體儲存記憶體斷點相關資訊:

Typedef struct membrakpointinfo

Dword unrecognized;//0x4d8138~0x40813b 未知

Dwordmemaddr;   //0x4d813c~0x4d813f 記憶體斷點起始地址

Dword size;        //0x4d8140~0x4d8143:0x00000006 記憶體斷點長度

Dword base1;      //0x4d8144~0x4d8147記憶體斷點地址所在的記憶體頁起始地址

Dword base2;     //0x4d8148~0x4d814b:0x00402000 記憶體斷點尾部地址+記憶體也大小地址後,所在的記憶體頁起始地址

Dword memtype;  //0x4d814c~0x4d814f 記憶體斷點屬性

}

相關推薦

Windows記憶體OD記憶體斷點初步分析

記憶體斷點原理:        記憶體斷點原理,通過將記憶體斷點所在記憶體頁的屬性修改為記憶體斷點屬性(non-access or non-writable),程式執行時,對目標記憶體頁中所有資料的訪問或寫,都會丟擲異常,OD通過截獲此異常,然後對比,儲存在某一記憶體的

Windows 記憶體Windows記憶體管理

本文主要內容: 1.基本概念:實體記憶體、虛擬記憶體;實體地址、虛擬地址、邏輯地址;頁目錄,頁表 2.Windows記憶體管理 3.CPU段式記憶體管理 4.CPU頁式記憶體管理   一、基本概念 1. 兩個記憶體概念 實體記憶體:人盡皆知,就是插在主機板上的記憶體條。他

elastic-job:失效轉移

shard out utm monit 設置 borde 點滴 title 等於 elastic-job中最關鍵的特性之一就是失效轉移。配置了失效轉移之後,如果在任務執行過程中有一個執行實例掛了,那麽之前被分配到這個實例的任務(或者分片)會在下次任務執行之前被重新分配到其他

郵件實現------JavaMail 發送帶圖片和附件和接收郵件

發送 網絡圖 發送對象 true n) com 訪問權限 sub map   好了,進入這個系列教程最主要的步驟了,前面郵件的理論知識我們都了解了,那麽這篇博客我們將用代碼完成郵件的發送。這在實際項目中應用的非常廣泛,比如註冊需要發送郵件進行賬號激活,再比如OA項目中利用郵

Quartz學習——SSMM(Spring+SpringMVC+Mybatis+Mysql)和Quartz集成

webapp cron表達式 msi 接口 cli post 定時 報錯 gets Quartz學習——SSMM(Spring+SpringMVC+Mybatis+Mysql)和Quartz集成詳解(四) 當任何時候覺你得難受了,其實你的大腦是在進化,當任何時候你覺得

07-Linux中DNS

用戶 mail all 驗證 src 更改 條目 http nslookup 接“06-Linux中DNS詳解(三)” 九、配置主從DNS服務器實現域名解析容錯 1、實驗環境zhangyujia.com(192.168.80.100)為主區域,com(192.168.8

編碼原理---之字形掃描

便是 集中 img 詳解 工作 -- 漢字 如何 編碼原理 上一篇我們講到,經過量化後得到了諸多零值和整數值,本篇接下來講講編碼過程中過對這些值如何組織和處理,那就是ZigZag掃描嘍。 一、簡介 ZigZag掃描也稱作之字形掃描,何以得此稱謂,是因為其掃描的路徑特

Nginx模塊

nginx https fastcgi 一、Nginx之目錄瀏覽二、Nginx之log模塊三、Ning之gzip模塊四、Nginx之https服務五、Nginx之fastCGI模塊 一、配置Nginx提供目錄瀏覽功能 1.修改nginx配置文件 server { listen

Zookeeper:Zookeeper中的zkCli.sh客戶端使用

zkCli.sh zookeeper客戶端 最好配置上環境變量連接操作:zkCli.sh -timeout 1000 -r -server 127.0.0.1 # -timeout 設置客戶端和服務器之間的超時時長,單位毫秒 # -r 只讀模式,不加就是讀寫模式 # -server IP:PORT 要

Keepalived

mysql pan 節點 ios all -s 關閉 定義 interval 一.通過vrrp_script實現對集群資源的監控: Keepalived基礎HA功能時用到了vrrp_script這個模塊,此模塊專門用於對集群中服務資源進行監控。與此模塊一起使用

PE文件格式

ebs 位置 數位 地址 inf font pe文件 。。 地址轉換 PE文件格式詳解(四) 0x00 前言 上一篇介紹了區塊表的信息,以及如何在hexwrokshop找到區塊表。接下來,我們繼續深入了解區塊,並且學會文件偏移和虛擬地址轉換的知識。 0x01 區塊對齊值

PE檔案格式

PE檔案格式詳解(四) 0x00 前言   上一篇介紹了區塊表的資訊,以及如何在hexwrokshop找到區塊表。接下來,我們繼續深入瞭解區塊,並且學會檔案偏移和虛擬地址轉換的知識。 0x01 區塊對齊值   首先我們要知道啥事區塊對齊?為啥要區塊對齊?這個問題

安卓專案實戰之強大的網路請求框架okGo使用:Cookie的管理

Cookie概念相關 具體來說cookie機制採用的是在客戶端保持狀態的方案,而session機制採用的是在伺服器端保持狀態的方案。同時我們也看到,由於採用伺服器端保持狀態的方案在客戶端也需要儲存一個標識,所以session機制是需要藉助於cookie機制來達到儲存標識的目的,所謂ses

【SpringBoot學習之路】08.Springboot配置檔案

轉載宣告:商業轉載請聯絡作者獲得授權,非商業轉載請註明出處.原文來自 © 呆萌鍾【SpringBoot學習之路】08.Springboot配置檔案詳解(四)  自動配置原理 配置檔案到底能寫什麼?怎麼寫?自動配置原理; 配置檔案能配置的屬性參照

Java 反射機制

Java 反射機制詳解(四) 4. 反射與泛型  定義一個泛型類: public class DAO<T> { //根據id獲取一個物件 T get(Integer id){ return null; }

Redis底層 整數集合

一、集合概述         對於集合,STL 的 set 相信大家都不陌生,它的底層實現是紅黑樹。無論插入、刪除、查詢都是 O(log n) 的時間複雜度。當然,如果用雜湊表來實現集合,插入、刪除、查詢都可以達到 O(1)。那麼為什麼集合要用紅黑樹

Scala入門

IO /** * IO * Scala進行檔案寫操作,直接用的都是java中的I/O類(java.io.File) */ object TestIO { def main(args: Array[String]): Unit = { /

spring事務測試驗證

系列目錄 spring事務詳解(五)總結提高 一、引子 在第一節中我們知道spring為了支援資料庫事務的ACID四大特性,在底層原始碼中對事務定義了6個屬性:事務名稱、隔離級別、超時時間、是否只讀、傳播機制、回滾機制。其中隔離級別和傳播機制光看第一節的描述還是不夠的,需要實際測

Tkinter 元件:Radiobutton

Tkinter 元件詳解之Radiobutton Radiobutton(單選按鈕)元件用於實現多選一的問題。Radiobutton 元件可以包含文字或影象,每一個按鈕都可以與一個 Python 的函式或方法與之相關聯,當按鈕被按下時,對應的函式或方法將被自動執行。 Radiobutto