1. 程式人生 > >血戰上海灘無數條命

血戰上海灘無數條命

正常情況下英雄只有三條命,如下圖所示:
CE附加程序,搜尋3,當生命值沒有變化時,繼續搜尋三,當生命值變成2時,搜尋2,這樣確定一個地址,然後搜尋什麼改寫了改地址:(後來測試時,程式直接崩潰,我就改用ollgdbg附加程序,在CE搜到的地址處下記憶體寫斷點),得到如下地址:這樣就得到了改寫生命值的地址:0x00464428,然後使用IDA分析一下:可以看到當血量為0時,就會減一條命,這樣要想實現無數條的效果,只要將dec ecx nop掉就可以了。。。我們繼續分析為什麼遊戲一開始英雄是3條命,而不是100條命呢?.text:00464421 mov ecx, [edx+1B0h].text:00464427 dec ecx.text:00464428 mov [edx+1B0h], ecx ; hero_fate通過這段程式碼可以看到,英雄生命值儲存在0x00464421處edx+1B0h,我們可以猜測,edx是英雄的物件地址,偏移0x1b0是英雄血量的儲存地址
重新運行遊戲,CE附加程序,在.text:00464421 mov ecx, [edx+1B0h]處下斷點,執行:可以看到此時edx=0x0b0cec10,這個可能是英雄的基地址然後在CE中搜索0x0b0cec10看到一個地址0x005DEF0C顏色是綠色的,表示每次啟動時,該地址都儲存的是英雄的基地址。再次啟動遊戲,CE附加程序,在0x005DEF0C處檢視什麼地址改寫了改資料,運行遊戲:可以看到0x42dae8改寫了改地址,IDA分析一下:.text:0042D9C0 hero_create_write_address proc near ; CODE XREF: .text:0042D9C0 ; .text:0042D905p.text:0042D9C0.text:0042D9C0 var_C = dword ptr -0Ch.text:0042D9C0 var_8 = dword ptr -8.text:0042D9C0 var_4 = dword ptr -4.text:0042D9C0.text:0042D9C0 sub esp, 0Ch.text:0042D9C3 push ebx.text:0042D9C4 push esi.text:0042D9C5 push edi.text:0042D9C6 mov esi, ecx.text:0042D9C8 call sub_452840.text:0042D9CD xor ebx, ebx.text:0042D9CF lea ecx, [esi+124h].text:0042D9D5 mov [esi+9Ch], ebx.text:0042D9DB mov [esi+0A0h], ebx.text:0042D9E1 mov [esi+0A4h], ebx.text:0042D9E7 mov [esi+0A8h], ebx.text:0042D9ED mov [esi+0ACh], ebx.text:0042D9F3 mov [esi+0B0h], ebx.text:0042D9F9 mov [esi+0B4h], ebx.text:0042D9FF mov [esi+0B8h], ebx.text:0042DA05 mov [esi+0BCh], ebx.text:0042DA0B mov [esi+0C0h], ebx.text:0042DA11 mov [esi+0C4h], ebx.text:0042DA17 mov [esi+0C8h], ebx.text:0042DA1D mov [esi+0CCh], ebx.text:0042DA23 mov [esi+0D0h], ebx.text:0042DA29 mov [esi+0D4h], ebx.text:0042DA2F call sub_42D980.text:0042DA34 mov ecx, 12h.text:0042DA39 xor eax, eax.text:0042DA3B lea edi, [esi+1B8h].text:0042DA41 mov edx, ebx.text:0042DA43 rep stosd.text:0042DA45 lea ecx, [esi+0D8h].text:0042DA4B mov [esp+18h+var_8], 3F800000h.text:0042DA53 mov al, 1.text:0042DA55 mov dword ptr [esi], offset off_58EA58.text:0042DA5B mov [ecx], edx.text:0042DA5D mov edx, [esp+18h+var_8].text:0042DA61 mov [esi+94h], al.text:0042DA67 mov [esi+0FCh], al.text:0042DA6D mov [ecx+4], edx.text:0042DA70 mov edx, ebx.text:0042DA72 mov [esi+104h], al.text:0042DA78 xor eax, eax.text:0042DA7A mov [ecx+8], edx.text:0042DA7D lea ecx, [esi+108h].text:0042DA83 mov [esi+98h], ebx.text:0042DA89 mov [esi+0F0h], ebx.text:0042DA8F mov [esi+100h], ebx.text:0042DA95 mov dword ptr [esi+0E4h], 3F666666h.text:0042DA9F mov [esi+0ECh], ebx.text:0042DAA5 mov [esi+0E8h], ebx.text:0042DAAB mov dword ptr [esi+0F4h], 0BF800000h.text:0042DAB5 mov dword ptr [esi+0F8h], 0FFFFFFFFh.text:0042DABF mov [esi+90h], ebx.text:0042DAC5 mov [esi+11Ch], ebx.text:0042DACB mov [ecx], eax.text:0042DACD pop edi.text:0042DACE mov [esp+14h+var_C], ebx.text:0042DAD2 mov [esp+14h+var_4], ebx.text:0042DAD6 mov [ecx+4], eax.text:0042DAD9 mov [ecx+8], eax.text:0042DADC mov [ecx+0Ch], eax.text:0042DADF mov [ecx+10h], eax.text:0042DAE2 mov [esi+120h], bl.text:0042DAE8 mov dword_5DEF0C, esi
.text:0042DAEE mov [esi+121h], bl.text:0042DAF4 mov eax, esi.text:0042DAF6 pop esi.text:0042DAF7 pop ebx.text:0042DAF8 add esp, 0Ch.text:0042DAFB retn.text:0042DAFB hero_create endp.text:0042DAFB可以看到該函式(hero_create_write_address)就是給esi的偏移賦值,然後將esi地址(也就是英雄基地址)寫入固定地址dword_5DEF0處,但是沒有發現對該地址的偏移0x1b0賦值,檢視下該函式的呼叫情況:
可以看到該函式(heap_create)建立了一個大小為0x200的堆,然後為該堆賦值。然後在改地址偏移0x1b0處下記憶體寫斷點,檢視什麼改寫了改地址:用IDA分析一下:可以看到此時就是將3條命寫入建立堆偏移0x1b0處然後看一下函式呼叫順序:hero_create->hero_create_write_address->hero_create_write_fate_1->hero_create_write_fate要實現無數條命的辦法就是將0x0042F1A5處 mov dword ptr [edi+1B0h], 3 的3修改為任意值,就可以實現無數條命的效果了 。