ฉันจะค้นหาโครงสร้างข้อมูลที่แสดงถึงเลย์เอาต์ของ Minesweeper ในหน่วยความจำได้อย่างไร


94

ฉันกำลังพยายามเรียนรู้เกี่ยวกับวิศวกรรมย้อนกลับโดยใช้ Minesweeper เป็นแอปพลิเคชันตัวอย่าง ฉันพบบทความ MSDNเกี่ยวกับคำสั่ง WinDbg ง่ายๆที่เปิดเผยการขุดทั้งหมด แต่เก่าแล้วไม่มีการอธิบายรายละเอียดใด ๆ และไม่ใช่สิ่งที่ฉันกำลังมองหา

ฉันมีIDA Pro disassemblerและตัวแก้จุดบกพร่อง WinDbgและฉันได้โหลด winmine.exe ลงในทั้งสองตัว ใครสามารถให้คำแนะนำที่เป็นประโยชน์สำหรับโปรแกรมเหล่านี้ในแง่ของการค้นหาตำแหน่งของโครงสร้างข้อมูลที่แสดงถึงเขตข้อมูลของฉัน

ใน WinDbg ฉันสามารถตั้งค่าเบรกพอยต์ได้ แต่มันยากสำหรับฉันที่จะจินตนาการว่าจุดใดที่จะตั้งเบรกพอยต์และตำแหน่งหน่วยความจำใด ในทำนองเดียวกันเมื่อฉันดูรหัสคงที่ใน IDA Pro ฉันไม่แน่ใจว่าจะเริ่มหาฟังก์ชันหรือโครงสร้างข้อมูลที่แสดงถึงเขตข้อมูลของฉันได้ที่ไหน

มี Reverse Engineers บน Stackoverflow ที่สามารถชี้ฉันไปในทิศทางที่ถูกต้องหรือไม่?


27
ช่างเป็นความคิดที่ดีมากสำหรับงานมอบหมายสำหรับนักเรียน มันคล้ายกับห้องปฏิบัติการกายวิภาคศาสตร์ที่มีเรือกวาดทุ่นระเบิดเป็นแมว
ojblass

3
สำหรับผู้อ่านต่างประเทศของเราที่อาจสับสนเรือกวาดทุ่นระเบิดเป็นเกมค้นหาดอกไม้แห่งความสุขเวอร์ชั่นอเมริกันที่มาพร้อมกับ windows vista microsoft.blognewschannel.com/index.php/archives/2006/09/28/…
กีบ

16
เกมหาดอกไม้แสนสุข? O_o ความถูกต้องทางการเมืองไปไกลเกินไปแล้ว
ยูจีน

10
เวอร์ชันกวาดทุ่นระเบิดเป็นค่าเริ่มต้นอย่างน้อยใน Vista เวอร์ชันสวีเดน ฉันคิดว่าพวกเขาเริ่มต้นใช้เวอร์ชัน happy-flowers ในสถานที่ที่เหมืองมักจะระเบิดเด็ก ๆ เป็นชิ้น ๆ
JesperE

1
ดังนั้น ... เพียงแค่คลิกที่สี่เหลี่ยมแบบสุ่มเพื่อดูว่าพวกมันเป็นเหมืองไม่เป็นประโยชน์สำหรับสิ่งนี้เหรอ?
Smandoli

คำตอบ:


125

ส่วนที่ 1 จาก 3


หากคุณจริงจังกับการทำวิศวกรรมย้อนกลับอย่าลืมเทรนเนอร์และเครื่องมือโกง

วิศวกรย้อนกลับที่ดีควรทำความรู้จักกับ OS, ฟังก์ชัน Core API, โครงสร้างทั่วไปของโปรแกรม (run loop คืออะไร, โครงสร้าง windows, กิจวัตรการจัดการเหตุการณ์), รูปแบบไฟล์ (PE) "การเขียนโปรแกรม Windows" แบบคลาสสิกของ Petzold สามารถช่วยได้ (www.amazon.com/exec/obidos/ISBN=157231995X) รวมทั้ง MSDN ออนไลน์

อันดับแรกคุณควรคิดว่าสามารถเรียกรูทีนการเริ่มต้นทุ่นระเบิดได้ที่ไหน ฉันคิดตาม:

  • เมื่อคุณเปิดเกม
  • เมื่อคุณคลิกหน้ามีความสุข
  • เมื่อคุณคลิก Game-> New หรือกด F2
  • เมื่อคุณเปลี่ยนระดับความยาก

ฉันตัดสินใจตรวจสอบคำสั่งตัวเร่งความเร็ว F2

หากต้องการค้นหารหัสการจัดการตัวเร่งความเร็วคุณจะต้องค้นหาขั้นตอนการจัดการข้อความหน้าต่าง (WndProc) สามารถสืบค้นกลับโดยการเรียก CreateWindowEx และ RegisterClass

อ่าน:

เปิด IDA หน้าต่างนำเข้าค้นหา "CreateWindow *" ข้ามไปที่มันและใช้คำสั่ง "Jump xref to operand (X)" เพื่อดูว่ามันถูกเรียกไปที่ใด ควรมีเพียงสายเดียว

ตอนนี้มองหาฟังก์ชัน RegisterClass ด้านบนและเป็นพารามิเตอร์ WndClass.lpfnWndProc ฉันตั้งชื่อฟังก์ชั่น mainWndProc ในกรณีของฉันแล้ว

.text:0100225D                 mov     [ebp+WndClass.lpfnWndProc], offset mainWndProc
.text:01002264                 mov     [ebp+WndClass.cbClsExtra], edi
.text:01002267                 mov     [ebp+WndClass.cbWndExtra], edi
.text:0100226A                 mov     [ebp+WndClass.hInstance], ecx
.text:0100226D                 mov     [ebp+WndClass.hIcon], eax

.text:01002292                 call    ds:RegisterClassW

กด Enter ที่ชื่อฟังก์ชัน (ใช้ 'N' เพื่อเปลี่ยนชื่อเป็นสิ่งที่ดีกว่า)

ตอนนี้มาดูที่

.text:01001BCF                 mov     edx, [ebp+Msg]

นี่คือรหัสข้อความซึ่งในกรณีของการกดปุ่ม F2 ควรมีค่า WM_COMMAND คุณต้องหาที่เทียบกับ 111h สามารถทำได้โดยการติดตาม edx ใน IDA หรือโดยการตั้งค่าเบรกพอยต์ตามเงื่อนไขใน WinDbg แล้วกด F2 ในเกม

ทั้งสองวิธีนำไปสู่สิ่งที่ชอบ

.text:01001D5B                 sub     eax, 111h
.text:01001D60                 jz      short loc_1001DBC

คลิกขวาที่ 111h และใช้ "Symbolic constant" -> "Use standard symbolic constant" พิมพ์ WM_ และ Enter ตอนนี้คุณควรมี

.text:01001D5B                 sub     eax, WM_COMMAND
.text:01001D60                 jz      short loc_1001DBC

เป็นวิธีง่ายๆในการค้นหาค่ารหัสข้อความ

หากต้องการทำความเข้าใจเกี่ยวกับการจัดการคันเร่งให้ตรวจสอบ:

มีข้อความค่อนข้างมากสำหรับคำตอบเดียว หากคุณสนใจฉันสามารถเขียนโพสต์อื่น ๆ ได้ เขตที่วางทุ่นระเบิดเรื่องสั้นขนาดยาวที่จัดเก็บเป็นอาร์เรย์ของไบต์ [24x36] 0x0F แสดงว่าไม่ได้ใช้ไบต์ (เล่นฟิลด์เล็กกว่า) 0x10 - ฟิลด์ว่าง 0x80 - ของฉัน

ส่วนที่ 2 จาก 3


โอเคไปต่อด้วยปุ่ม F2

ตามการใช้ Keyboard Acceleratorsเมื่อกดปุ่ม F2 ฟังก์ชัน wndProc

... ได้รับข้อความ WM_COMMAND หรือ WM_SYSCOMMAND คำลำดับต่ำของพารามิเตอร์ wParam มีตัวระบุของตัวเร่ง

ตกลงเราพบแล้วว่า WM_COMMAND ประมวลผลที่ไหน แต่จะกำหนดค่าพารามิเตอร์ wParam ที่เกี่ยวข้องได้อย่างไร นี่คือจุดที่แฮ็กเกอร์ทรัพยากรเข้ามามีบทบาท ป้อนด้วยไบนารีและแสดงให้คุณเห็นทุกอย่าง เช่นเดียวกับตารางเร่งสำหรับฉัน

ข้อความแสดงแทน http://files.getdropbox.com/u/1478671/2009-07-29_161532.jpg

คุณสามารถดูได้ที่นี่ปุ่ม F2 นั้นตรงกับ 510 ใน wParam

ตอนนี้ขอกลับไปที่รหัสที่จัดการ WM_COMMAND มันเปรียบเทียบ wParam กับค่าคงที่ต่างกัน

.text:01001DBC HandleWM_COMMAND:                       ; CODE XREF: mainWndProc+197j
.text:01001DBC                 movzx   eax, word ptr [ebp+wParam]
.text:01001DC0                 mov     ecx, 210h
.text:01001DC5                 cmp     eax, ecx
.text:01001DC7                 jg      loc_1001EDC
.text:01001DC7
.text:01001DCD                 jz      loc_1001ED2
.text:01001DCD
.text:01001DD3                 cmp     eax, 1FEh
.text:01001DD8                 jz      loc_1001EC8

ใช้เมนูบริบทหรือแป้นพิมพ์ลัด 'H' เพื่อแสดงค่าทศนิยมและคุณจะเห็นการกระโดดของเรา

.text:01001DBC HandleWM_COMMAND:                       ; CODE XREF: mainWndProc+197j
.text:01001DBC                 movzx   eax, word ptr [ebp+wParam]
.text:01001DC0                 mov     ecx, 528
.text:01001DC5                 cmp     eax, ecx
.text:01001DC7                 jg      loc_1001EDC
.text:01001DC7
.text:01001DCD                 jz      loc_1001ED2
.text:01001DCD
.text:01001DD3                 cmp     eax, 510
.text:01001DD8                 jz      loc_1001EC8 ; here is our jump

มันนำไปสู่โค้ดที่เรียก proc บางตัวและออกจาก wndProc

.text:01001EC8 loc_1001EC8:                            ; CODE XREF: mainWndProc+20Fj
.text:01001EC8                 call    sub_100367A     ; startNewGame ?
.text:01001EC8
.text:01001ECD                 jmp     callDefAndExit  ; default

เป็นฟังก์ชันที่เริ่มเกมใหม่หรือไม่? ค้นหาในส่วนสุดท้าย! คอยติดตาม.

ส่วนที่ 3 ของ 3

มาดูส่วนแรกของฟังก์ชันนั้นกัน

.text:0100367A sub_100367A     proc near               ; CODE XREF: sub_100140C+CAp
.text:0100367A                                         ; sub_1001B49+33j ...
.text:0100367A                 mov     eax, dword_10056AC
.text:0100367F                 mov     ecx, uValue
.text:01003685                 push    ebx
.text:01003686                 push    esi
.text:01003687                 push    edi
.text:01003688                 xor     edi, edi
.text:0100368A                 cmp     eax, dword_1005334
.text:01003690                 mov     dword_1005164, edi
.text:01003696                 jnz     short loc_10036A4
.text:01003696
.text:01003698                 cmp     ecx, dword_1005338
.text:0100369E                 jnz     short loc_10036A4

มีสองค่า (dword_10056AC, uValue) ที่อ่านในรีจิสเตอร์ eax และ ecx และเปรียบเทียบกับอีกสองค่า (dword_1005164, dword_1005338)

ลองดูค่าจริงโดยใช้ WinDBG ('bp 01003696'; on break 'p eax; p ecx') - ดูเหมือนว่าขนาดพื้นที่ทุ่นระเบิดสำหรับฉัน การเล่นกับขนาดพื้นที่ทุ่นระเบิดที่กำหนดเองแสดงให้เห็นว่าคู่แรกเป็นมิติใหม่และมิติที่สอง - ปัจจุบัน มาตั้งชื่อใหม่

.text:0100367A startNewGame    proc near               ; CODE XREF: handleButtonPress+CAp
.text:0100367A                                         ; sub_1001B49+33j ...
.text:0100367A                 mov     eax, newMineFieldWidth
.text:0100367F                 mov     ecx, newMineFieldHeight
.text:01003685                 push    ebx
.text:01003686                 push    esi
.text:01003687                 push    edi
.text:01003688                 xor     edi, edi
.text:0100368A                 cmp     eax, currentMineFieldWidth
.text:01003690                 mov     dword_1005164, edi
.text:01003696                 jnz     short loc_10036A4
.text:01003696
.text:01003698                 cmp     ecx, currentMineFieldHeight
.text:0100369E                 jnz     short loc_10036A4

ค่าใหม่ในภายหลังเล็กน้อยจะเขียนทับปัจจุบันและเรียกรูทีนย่อย

.text:010036A7                 mov     currentMineFieldWidth, eax
.text:010036AC                 mov     currentMineFieldHeight, ecx
.text:010036B2                 call    sub_1002ED5

และเมื่อฉันเห็นมัน

.text:01002ED5 sub_1002ED5     proc near               ; CODE XREF: sub_1002B14:loc_1002B1Ep
.text:01002ED5                                         ; sub_100367A+38p
.text:01002ED5                 mov     eax, 360h
.text:01002ED5
.text:01002EDA
.text:01002EDA loc_1002EDA:                            ; CODE XREF: sub_1002ED5+Dj
.text:01002EDA                 dec     eax
.text:01002EDB                 mov     byte ptr dword_1005340[eax], 0Fh
.text:01002EE2                 jnz     short loc_1002EDA

ฉันแน่ใจอย่างสมบูรณ์ว่าฉันพบอาร์เรย์ของทุ่นระเบิด สาเหตุของวงจรซึ่งอยู่ในอาร์เรย์ความยาว 360h ไบต์ (dword_1005340) ด้วย 0xF

ทำไม 360h = 864? มีบางตัวชี้นำด้านล่างแถวนั้นใช้เวลา 32 ไบต์และ 864 สามารถหารด้วย 32 ดังนั้นอาร์เรย์จึงสามารถเก็บเซลล์ 27 * 32 ได้ (แม้ว่า UI จะอนุญาตฟิลด์ 24 * 30 สูงสุด แต่ก็มีช่องว่างภายในหนึ่งไบต์รอบอาร์เรย์สำหรับเส้นขอบ)

โค้ดต่อไปนี้จะสร้างเส้นขอบด้านบนและด้านล่างของทุ่นระเบิด (0x10 ไบต์) ฉันหวังว่าคุณจะเห็นการวนซ้ำในระเบียบนั้น) ฉันต้องใช้กระดาษและปากกา

.text:01002EE4                 mov     ecx, currentMineFieldWidth
.text:01002EEA                 mov     edx, currentMineFieldHeight
.text:01002EF0                 lea     eax, [ecx+2]
.text:01002EF3                 test    eax, eax
.text:01002EF5                 push    esi
.text:01002EF6                 jz      short loc_1002F11    ; 
.text:01002EF6
.text:01002EF8                 mov     esi, edx
.text:01002EFA                 shl     esi, 5
.text:01002EFD                 lea     esi, dword_1005360[esi]
.text:01002EFD
.text:01002F03 draws top and bottom borders
.text:01002F03 
.text:01002F03 loc_1002F03:                            ; CODE XREF: sub_1002ED5+3Aj
.text:01002F03                 dec     eax
.text:01002F04                 mov     byte ptr MineField?[eax], 10h ; top border
.text:01002F0B                 mov     byte ptr [esi+eax], 10h       ; bottom border
.text:01002F0F                 jnz     short loc_1002F03
.text:01002F0F
.text:01002F11
.text:01002F11 loc_1002F11:                            ; CODE XREF: sub_1002ED5+21j
.text:01002F11                 lea     esi, [edx+2]
.text:01002F14                 test    esi, esi
.text:01002F16                 jz      short loc_1002F39

และรูทีนย่อยที่เหลือจะดึงเส้นขอบซ้ายและขวา

.text:01002F18                 mov     eax, esi
.text:01002F1A                 shl     eax, 5
.text:01002F1D                 lea     edx, MineField?[eax]
.text:01002F23                 lea     eax, (MineField?+1)[eax+ecx]
.text:01002F23
.text:01002F2A
.text:01002F2A loc_1002F2A:                            ; CODE XREF: sub_1002ED5+62j
.text:01002F2A                 sub     edx, 20h
.text:01002F2D                 sub     eax, 20h
.text:01002F30                 dec     esi
.text:01002F31                 mov     byte ptr [edx], 10h
.text:01002F34                 mov     byte ptr [eax], 10h
.text:01002F37                 jnz     short loc_1002F2A
.text:01002F37
.text:01002F39
.text:01002F39 loc_1002F39:                            ; CODE XREF: sub_1002ED5+41j
.text:01002F39                 pop     esi
.text:01002F3A                 retn

การใช้คำสั่ง WinDBG อย่างชาญฉลาดสามารถให้การถ่ายโอนข้อมูลทุ่นระเบิดที่ยอดเยี่ยม (ขนาดที่กำหนดเอง 9x9) ตรวจสอบพรมแดน!

0:000> db /c 20 01005340 L360
01005340  10 10 10 10 10 10 10 10-10 10 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005360  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005380  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
010053a0  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
010053c0  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
010053e0  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005400  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005420  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005440  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005460  10 0f 0f 0f 0f 0f 0f 0f-0f 0f 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
01005480  10 10 10 10 10 10 10 10-10 10 10 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
010054a0  0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
010054c0  0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................
010054e0  0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f 0f  ................................

อืมดูเหมือนว่าฉันจะต้องการโพสต์อื่นเพื่อปิดหัวข้อนี้


1
@Stanislav คำตอบที่ดี Stanislav หากคุณสามารถอธิบายอย่างละเอียดได้โปรดดำเนินการดังกล่าว คำตอบที่ยาวและให้ข้อมูลเหล่านี้ดีที่สุด อาจจะเพิ่มเติมอีกเล็กน้อยเกี่ยวกับวิธีที่คุณเป็นศูนย์ในโครงสร้างข้อมูลของทุ่นระเบิด?
KingNestor

@Stanislav ฉันยอมรับคำตอบของคุณแล้วเพราะ 250 rep bounty กำลังจะสิ้นสุดลง ยินดีด้วย!
KingNestor

1
@Stanislav ฉันแก้ไขคำตอบหลายส่วนของคุณเป็นคำตอบเดียว คุณยังไม่ถึงขีด จำกัด ขนาดของคำตอบเดียวของคุณและฉันคิดว่าโดยทั่วไปแล้วควรมีคำตอบเดียวแทนที่จะโพสต์หลายคำ อย่าลังเลที่จะแก้ไขคำตอบเดิมของคุณ (อันนี้) และเพิ่มคำตอบตามที่เห็นสมควร
mmcdole

2
นอกจากนี้คำตอบมหากาพย์ Stanislav ขอบคุณมากสำหรับการทำงานหนักของคุณ!
mmcdole

15

ดูเหมือนว่าคุณกำลังพยายามแยกส่วนซอร์สออก แต่สิ่งที่คุณต้องทำคือดูพื้นที่หน่วยความจำของโปรแกรมที่กำลังทำงานอยู่ ตัวแก้ไขฐานสิบหกHxDมีคุณสมบัติที่ช่วยให้คุณทำได้

http://www.freeimagehosting.net/uploads/fcc1991162.png

เมื่อคุณอยู่ในพื้นที่หน่วยความจำมันเป็นเรื่องของการถ่ายภาพรวมของหน่วยความจำในขณะที่คุณยุ่งกับบอร์ด แยกสิ่งที่เปลี่ยนแปลงกับสิ่งที่ไม่เปลี่ยนแปลง เมื่อคุณคิดว่าคุณสามารถจับตำแหน่งโครงสร้างข้อมูลในหน่วยความจำฐานสิบหกได้ให้ลองแก้ไขในขณะที่อยู่ในหน่วยความจำและดูว่าบอร์ดเปลี่ยนไปหรือไม่

กระบวนการที่คุณต้องการไม่ต่างจากการสร้าง 'เทรนเนอร์' สำหรับวิดีโอเกม สิ่งเหล่านี้มักขึ้นอยู่กับการค้นหาว่าค่าต่างๆเช่นสุขภาพและกระสุนอยู่ในหน่วยความจำที่ใดและเปลี่ยนแปลงได้ทันที คุณอาจพบบทเรียนดีๆเกี่ยวกับวิธีสร้างผู้ฝึกสอนเกม


2
คุณ ~ สามารถ ~ ค้นหาตำแหน่งหน่วยความจำผ่านการถอดแบบคงที่ คุณสามารถทำตามคำแนะนำในการประกอบเพื่อค้นหาสิ่งต่างๆเช่นฟังก์ชัน rand () ที่ถูกเรียกให้สร้างฟิลด์ทุ่นระเบิดจากนั้นติดตามจากที่นั่นเพื่อดูตำแหน่งที่ฟิลด์ถูกเก็บไว้ในหน่วยความจำ (และอย่างไร)
mmcdole

ทั้งสองแนวทางมีความท้าทาย ฉันเคยพยายามแยกชิ้นส่วนแอปพลิเคชันในอดีตและฉันพบว่ามันเจ็บปวดมาก คุณมองเห็นฟังก์ชัน Rand () ได้อย่างไร?
James McMahon

ขอบคุณสำหรับคำตอบของคุณ nemo
KingNestor

11

ตรวจสอบบทความโครงการรหัสนี้มีความลึกมากกว่าบทความในบล็อกที่คุณกล่าวถึงเล็กน้อย

http://www.codeproject.com/KB/trace/minememoryreader.aspx

แก้ไข

และบทความนี้แม้ว่าจะไม่เกี่ยวกับเรือกวาดทุ่นระเบิดโดยตรง แต่ก็ให้คำแนะนำทีละขั้นตอนในการล่าสัตว์ผ่านหน่วยความจำโดยใช้ WinDbg:

http://www.codingthewheel.com/archives/extracting-hidden-text-with-windbg

แก้ไข 2

อีกครั้งนี่ไม่ได้เกี่ยวกับเรือกวาดทุ่นระเบิด แต่มันให้อาหารฉันอย่างแน่นอนสำหรับความคิดในการแก้ไขจุดบกพร่องหน่วยความจำของฉันมีบทเรียนมากมายที่นี่:

http://memoryhacking.com/forums/index.php

ดาวน์โหลดCheatEngine (กล่าวถึงโดย Nick D. ) และทำงานผ่านบทช่วยสอนที่มาพร้อมกับ


9

"ใน WinDbg ฉันสามารถตั้งค่าจุดพักได้ แต่มันยากสำหรับฉันที่จะจินตนาการว่าจุดใดที่จะตั้งเบรกพอยต์และตำแหน่งหน่วยความจำตำแหน่งใดในทำนองเดียวกันเมื่อฉันดูรหัสคงที่ใน IDA Pro ฉันไม่แน่ใจว่าจะเริ่มจากจุดใด เพื่อค้นหาฟังก์ชันหรือโครงสร้างข้อมูลที่แสดงถึงเขตข้อมูลของฉัน "

เป๊ะ!

คุณสามารถมองหากิจวัตรเช่น random () ที่จะถูกเรียกในระหว่างการสร้างตารางเหมืองแร่ หนังสือเล่มนี้ช่วยฉันได้มากตอนทดลองวิศวกรรมย้อนรอย :)

โดยทั่วไปสถานที่ที่ดีสำหรับการตั้งค่าจุดพักคือการโทรไปยังกล่องข้อความการโทรเพื่อเล่นเสียงตัวจับเวลาและรูทีน win32 API อื่น ๆ

BTW, ฉันกำลังสแกนเรือกวาดทุ่นระเบิดในขณะนี้กับOllyDbg

อัปเดต: nemoทำให้ฉันนึกถึงเครื่องมือที่ยอดเยี่ยมCheat Engineโดย Eric "Dark Byte" Heijnen

Cheat Engine (CE) เป็นเครื่องมือที่ยอดเยี่ยมสำหรับการดูและปรับเปลี่ยนพื้นที่หน่วยความจำของกระบวนการอื่น ๆ นอกเหนือจากสิ่งอำนวยความสะดวกพื้นฐานแล้ว CE ยังมีคุณสมบัติพิเศษอื่น ๆ อีกเช่นการดูหน่วยความจำที่แยกส่วนของกระบวนการและการฉีดรหัสลงในกระบวนการอื่น ๆ

( มูลค่าที่แท้จริงของโครงการนั้นคือคุณสามารถดาวน์โหลดซอร์สโค้ด -Delphi- และดูว่ากลไกเหล่านั้นถูกนำไปใช้อย่างไร - ฉันทำอย่างนั้นเมื่อหลายปีก่อน: o)


5

บทความที่ดีงามในหัวข้อนี้มากสามารถพบได้ที่ไม่รู้ ครอบคลุมถึงการย้อนกลับ Minesweeper (เป็นบทนำของแอป Win32 วิศวกรรมย้อนกลับ) ในรายละเอียดที่ค่อนข้างดีและเป็นแหล่งข้อมูลที่ยอดเยี่ยมทีเดียว


4

เว็บไซต์นี้อาจมีประโยชน์มากกว่านี้:

http://www.subversity.net/reversing/hacking-minesweeper

วิธีทั่วไปในการดำเนินการนี้คือ:

  1. รับซอร์สโค้ดอย่างใด
  2. แยกชิ้นส่วนและหวังว่าสัญลักษณ์ที่เหลือจะช่วยคุณได้
  3. เดาประเภทข้อมูลและพยายามจัดการและใช้เครื่องสแกนหน่วยความจำเพื่อจำกัดความเป็นไปได้

เพื่อตอบสนองต่อ Bounty

ในการอ่านครั้งที่สองดูเหมือนว่าคุณต้องการคำแนะนำเกี่ยวกับวิธีใช้ดีบักเกอร์เช่น WinDBG แทนที่จะเป็นคำถามปกติเกี่ยวกับวิธีการทำวิศวกรรมย้อนกลับ ฉันได้แสดงเว็บไซต์ที่บอกค่าที่คุณต้องการค้นหาแล้วคำถามคือคุณจะค้นหาได้อย่างไร

ฉันใช้ Notepad ในตัวอย่างนี้เนื่องจากไม่ได้ติดตั้ง Minesweeper แต่ความคิดเหมือนกัน.

ข้อความแสดงแทน

คุณพิมพ์

s <options> <memory start> <memory end> <pattern>

กด "?" แล้วกด "s" เพื่อดูวิธีใช้

เมื่อคุณพบรูปแบบหน่วยความจำที่คุณต้องการแล้วคุณสามารถกด alt + 5 เพื่อเปิดโปรแกรมดูหน่วยความจำสำหรับการแสดงผลที่สวยงาม

ข้อความแสดงแทน

WinDBG ใช้เวลาในการทำความคุ้นเคย แต่ก็ดีพอ ๆ กับดีบักเกอร์อื่น ๆ


1
"รับซอร์สโค้ด" เป็นคำพูดที่ไร้สาระเนื่องจาก Minesweeper ถูกส่งโดยไม่มีแหล่งที่มา และวิศวกรรมย้อนกลับกับแหล่งที่มาไม่ใช่วิศวกรรมย้อนกลับ ... เป็นการวิเคราะห์ซอร์สโค้ด
mrduclaw

@mrduclaw มีแอพพลิเคชั่นที่สามารถถอดรหัสแอสเซมบลีเป็นภาษาต้นทางได้ ไม่มีคำที่เรียกว่า "การวิเคราะห์ซอร์สโค้ด"
ไม่ทราบ

1
@Unknown มีแอพพลิเคชั่นที่พยายามสร้างโปรแกรมขึ้นมาใหม่ในภาษาต้นทางจากไบนารีที่คอมไพล์ที่กำหนด แต่คุณไม่สามารถรับ "ซอร์สโค้ด" พร้อมกับความคิดเห็นและใบเสนอราคาของผู้เขียนจากไบนารีที่คอมไพล์ แน่นอนว่า "ตัวถอดรหัส" บางตัวทำงานได้ดีกว่าคนอื่น ๆ แต่ไม่ได้ให้รหัสที่ผู้เขียนเขียน (โค้ดที่ปรับให้เหมาะสมกับคอมไพเลอร์มักจะแตกต่างจากโค้ดของโปรแกรมเมอร์มาก) และคุณไม่เคยทำการทดสอบการประกันคุณภาพหรือไม่? เครื่องมืออย่าง PREfast และ Sparse ทำอะไรได้บ้าง? การวิเคราะห์ซอร์สโค้ดแบบคงที่
mrduclaw

การวิเคราะห์ซอร์สโค้ดแบบคงที่ใน PREfast และ Sparse นั้นแตกต่างอย่างสิ้นเชิงกับการอ่านโค้ดที่ถอดรหัสด้วยตนเองเพื่อแฮ็ค ฉันไม่คิดว่าจะมีใครสับสนทั้งสองความคิดที่แตกต่างกัน
ไม่ทราบ

@ ไม่ทราบฉันขออธิบายเพิ่มเติมและยอมรับว่าคุณไม่ควรสับสนระหว่างการถอดชิ้นส่วนวิศวกรรมย้อนกลับกับการดูซอร์สโค้ด (ถอดรหัสหรืออื่น ๆ หากคุณมีแหล่งที่มาที่คุณกำลังทำการวิเคราะห์ซอร์สโค้ด) นั่นคือจุดรวมของฉัน ดังนั้นโปรดหยุดสับสนทั้งสอง :)
mrduclaw

0

จุดที่ดีในการเริ่มต้นการติดตามในดีบักเกอร์คือเมื่อเมาส์ขึ้น ดังนั้นค้นหาขั้นตอนหน้าต่างหลัก (ฉันคิดว่าเครื่องมือเช่น spyxx สามารถตรวจสอบคุณสมบัติของ windows และที่อยู่ตัวจัดการเหตุการณ์เป็นหนึ่งในนั้น) เจาะเข้าไปและค้นหาว่ามันจัดการกับเหตุการณ์ของเมาส์ - จะมีสวิตช์หากคุณสามารถจดจำได้ในแอสเซมเบลอร์ (ดูที่ค่า WM_XXX สำหรับการเลื่อนเมาส์ใน windows.h)

วางเบรกพอยต์ที่นั่นและเริ่มก้าวเข้ามาในช่วงเวลาที่คุณปล่อยปุ่มเมาส์และหน้าจอที่กำลังอัปเดตชัยชนะจะเข้าถึงโครงสร้างข้อมูลที่คุณกำลังมองหา

อดทนพยายามระบุสิ่งที่กำลังทำในช่วงเวลาใดเวลาหนึ่ง แต่อย่ากังวลกับการมองลึกเข้าไปในโค้ดที่คุณสงสัยว่าไม่น่าสนใจสำหรับวัตถุประสงค์ปัจจุบันของคุณ อาจต้องใช้เวลาหลายครั้งในการดีบักเกอร์ในการแก้ไขปัญหา

ความรู้เกี่ยวกับขั้นตอนการทำงานของแอปพลิเคชัน win32 ปกติช่วยด้วย


0

เหมืองอาจถูกเก็บไว้ในอาร์เรย์สองมิติบางประเภท ซึ่งหมายความว่าเป็นอาร์เรย์ของพอยน์เตอร์หรือบูลีนสไตล์ C ชุดเดียว

เมื่อใดก็ตามที่ฟอร์มได้รับเหตุการณ์ที่วางเมาส์ขึ้นโครงสร้างข้อมูลนี้จะถูกอ้างอิง ดัชนีจะคำนวณโดยใช้พิกัดเมาส์โดยอาจใช้การหารจำนวนเต็ม นั่นหมายความว่าคุณอาจจะมองหาcmpหรือการเรียนการสอนที่คล้ายกันซึ่งเป็นหนึ่งในตัวถูกดำเนินการที่มีการคำนวณโดยใช้ชดเชยและxที่xเป็นผลมาจากการคำนวณที่เกี่ยวข้องกับการแบ่งจำนวนเต็ม จากนั้นออฟเซ็ตจะเป็นตัวชี้ไปที่จุดเริ่มต้นของโครงสร้างข้อมูล


0

เป็นเรื่องที่สมเหตุสมผลที่จะสมมติว่าข้อมูลเกี่ยวกับเหมืองถูกจัดวางอย่างต่อเนื่องในหน่วยความจำอย่างน้อยสำหรับแถว (เช่นเป็นอาร์เรย์ 2 มิติหรืออาร์เรย์ของอาร์เรย์) ดังนั้นฉันจะลองเปิดเซลล์ที่อยู่ติดกันหลายเซลล์ในแถวเดียวกันโดยทำการทิ้งหน่วยความจำของกระบวนการในขณะที่ฉันไปจากนั้นจึงแตกต่างกันและมองหาการเปลี่ยนแปลงที่เกิดขึ้นซ้ำ ๆ ในพื้นที่หน่วยความจำเดียวกัน (เช่น 1 ไบต์เปลี่ยนในขั้นตอนแรกถัดไป ไบต์เปลี่ยนเป็นค่าเดียวกันในขั้นตอนถัดไป ฯลฯ )

นอกจากนี้ยังมีความเป็นไปได้ที่จะเป็นอาร์เรย์บิตที่บรรจุ (3 บิตต่อเหมืองควรเพียงพอที่จะบันทึกสถานะที่เป็นไปได้ทั้งหมด - ปิด / เปิด, ของฉัน / ไม่มีของฉัน, ถูกตั้งค่าสถานะ / ไม่ถูกตั้งค่าสถานะ) ดังนั้นฉันจึงมองหาสิ่งนั้นด้วย ( รูปแบบจะทำซ้ำได้เช่นกันแม้ว่าจะมองเห็นได้ยากกว่า) แต่มันไม่ใช่โครงสร้างที่สะดวกในการจัดการและฉันไม่คิดว่าการใช้หน่วยความจำเป็นปัญหาคอขวดสำหรับเรือกวาดทุ่นระเบิดดังนั้นจึงไม่น่าจะใช้สิ่งนี้ได้


0

แม้ว่าจะไม่ใช่ "เครื่องมือของวิศวกรย้อนกลับ" อย่างเคร่งครัด แต่ของเล่นอื่น ๆ ที่แม้แต่คนงี่เง่าอย่างฉันก็สามารถใช้ได้ลองดูCheat EngineEngine ทำให้ค่อนข้างง่ายในการติดตามว่าส่วนใดของหน่วยความจำมีการเปลี่ยนแปลงเมื่อใดและยังมีข้อกำหนดสำหรับการติดตามส่วนหน่วยความจำที่เปลี่ยนแปลงผ่านพอยน์เตอร์ (แม้ว่าคุณอาจไม่ต้องการสิ่งนั้นก็ตาม) รวมบทช่วยสอนแบบโต้ตอบที่ดี

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.