逆向深入分析AHpack,植物战役活死人汉语第二版

时间:2019-09-23 02:20来源: 操作系统
00413184 |. E8 77E30100 |CALL PlantsVs.00431500 ; 地上的物料 00413189 |. 8D7424 10 |LEA ESI,DWORD PTR SS:[ESP+10] 0041318D |. 8BD3 |MOV EDX,EBX 0041318F |. E8 7C980000 |CALL PlantsVs.0041CA10 00413194 |. 84C0 |TEST AL,AL 00413196 |.^ 7

00413184 |. E8 77E30100 |CALL PlantsVs.00431500 ; 地上的物料
00413189 |. 8D7424 10 |LEA ESI,DWORD PTR SS:[ESP+10]
0041318D |. 8BD3 |MOV EDX,EBX
0041318F |. E8 7C980000 |CALL PlantsVs.0041CA10
00413194 |. 84C0 |TEST AL,AL
00413196 |.^ 75 E8 JNZ SHORT PlantsVs.00413180
00413198 |> 8D7424 10 LEA ESI,DWORD PTR SS:[ESP+10]
0041319C |. 8BD3 MOV EDX,EBX
0041319E |. 896C24 10 MOV DWORD PTR SS:[ESP+10],EBP
004131A2 |. E8 C9980000 CALL PlantsVs.0041CA70
004131A7 |. 84C0 TEST AL,AL
004131A9 |. 74 1E JE SHORT PlantsVs.004131C9
004131AB |. EB 03 JMP SHORT PlantsVs.004131B0
004131AD | 8D49 00 LEA ECX,DWORD PTR DS:[ECX]
004131B0 |> 8B4424 10 /MOV EAX,DWORD PTR SS:[ESP+10]
004131B4 |. 50 |PUSH EAX
004131B5 |. E8 26550400 |CALL PlantsVs.004586E0
004131BA |. 8D7424 10 |LEA ESI,DWORD PTR SS:[ESP+10]
004131BE |. 8BD3 |MOV EDX,EBX
004131C0 |. E8 AB980000 |CALL PlantsVs.0041CA70
004131C5 |. 84C0 |TEST AL,AL
004131C7 |.^ 75 E7 JNZ SHORT PlantsVs.004131B0

从暑假启幕逆向研商也许有二个半月了,明晚解析了三个压缩壳,第贰遍脱离书本逆向贰个前后相继,放上来记念一下。

004131C9 |> 8Bc3 3C010000 MOV EDI,DWORD PTR DS:[EBX+13C] ; edi = 游戏基址
004131CF |. E8 CC5B0200 CALL PlantsVs.00438DA0
004131D4 |. 8BB3 38010000 MOV ESI,DWORD PTR DS:[EBX+138]
004131DA |. E8 A1550200 CALL PlantsVs.00438780
004131DF |. 8B83 44010000 MOV EAX,DWORD PTR DS:[EBX+144]
004131E5 |. 33F6 XOR ESI,ESI
004131E7 |. 3968 24 CMP DWORD PTR DS:[EAX+24],EBP
004131EA |. 7E 1E JLE SHORT PlantsVs.0041320A
004131EC |. 33FF XOR EDI,EDI
004131EE |. 8BFF MOV EDI,EDI
004131F0 |> 8D4407 28 /LEA EAX,DWORD PTR DS:[EDI+EAX+28]
004131F4 |. E8 57400700 |CALL PlantsVs.00487250
004131F9 |. 8B83 44010000 |MOV EAX,DWORD PTR DS:[EBX+144]
004131FF |. 83C6 01 |ADD ESI,1
00413202 |. 83C7 50 |ADD EDI,50
00413205 |. 3B70 24 |CMP ESI,DWORD PTR DS:[EAX+24]
00413208 |.^ 7C E6 JL SHORT PlantsVs.004131F0
0041320A |> 5F POP EDI
0041320B |. 5E POP ESI
0041320C |. 5D POP EBP
0041320D |. 83C4 08 ADD ESP,8
00413210 . C3 RETN

实在像这种壳完全能够esp定律秒掉的,之所以深入分析它,是因为自己想清楚所谓IAT修复具体是怎么个算法,还应该有压缩壳到底流程是怎么着的,笔者感觉学逆向最大的童趣正是足以满意人的好奇心,只要精力够,程序的各种细节是怎么办的都能够了然。

00410A94 |. 52 PUSH EDX ; -1
00410A95 |. 50 PUSH EAX ; 植物类型
00410A96 |. 8B4424 20 MOV EAX,DWORD PTR SS:[ESP+20] ; Y
00410A9A |. 57 PUSH EDI ; X
00410A9B |. 55 PUSH EBP ; 游戏基址
00410A9C |. E8 7FC6FFFF CALL PlantsVs.0040D120

aplib部分看上去相比较烦,以自个儿今三门峡平去分析,那大概太烧脑子了。

修改器代码:

其实aplib部分本身感到小编本来应该是身处三个函数里的,那一个现象是编写翻译器优化所形成的

varForm1: TForm1;pGameBase:Pointer;pPlantBaseArray:array[0..100] of pointer;pMonBaseArray:array[0..100] of pointer;pGoodsBaseArray:array[0..100] of pointer;   pPlantToolBarBaseArray:array[0..100] of pointer;typestMonsterInfo = recordx:single;y:single;nMaxHP:integer;nCurHP:integer;nRow:integer;fSize:single;end;typestPlantToolBarInfo = recordnType:integer;nMaxRecovery:integer;nCurRecovery:integer;end;typestGoodsInfo = recordnType:integer;end;typestPlantInfo = recordbIsProdure:integer;nType:integer;end;implementation{$R *.dfm}procedure GetGameBase();beginasm    pushad    mov eax, $6a9ec0    mov eax, [eax]    add eax, $768    mov eax, [eax]    mov pGameBase, eax //游戏基址    popadend;end;function GetMonsterBase(pMonBase:Pointer):Pointer;beginasm    pushad    mov esi, pMonBase    mov edx, pGameBase//游戏基址    mov edi, $0041C8F0    call edi//获取一个怪物地址    popadend;Result:= Pointer(pMonBase^);end;function GetPlantBase(pPlantBase:Pointer):Pointer;beginasm    pushad    mov esi, pPlantBase    mov edx, pGameBase//游戏基址    mov edi, $0041C950    call edi//获取一个植物地址    popadend;Result:= Pointer(pPlantBase^);end;function GetGoodsBase(pGoodsBase:Pointer):Pointer;beginasm    pushad    mov esi, pGoodsBase    mov edx, pGameBase//游戏基址    mov edi, $0041CA10    call edi//获取一个植物地址    popadend;Result:= Pointer(pGoodsBase^);end;function GetPlantToolbarBase(nIndex:integer):Pointer;varpBase:Pointer;n:integer;beginn:= nIndex * $50 + $28;asmpushad    mov eax, pGameBase    mov eax, [eax + $144]    mov pBase, eaxpopadend;pBase:= Pointer(DWORD + n);Result:= pBase;end;function GetMaxPlantNum():integer;varn:integer;beginasm    pushad    mov eax, pGameBase    mov eax, [eax + $144]    mov eax, [eax + $24]    mov n, eax    popadend;Result:= n;end;procedure FreshMonsterList();varpMonBase:Integer;n, nIndex:integer;beginnIndex:= 0;pMonBase:= 0;n:= form1.RzComboBox1.ItemIndex;form1.RzComboBox1.Clear;repeat    pMonBase:= Integer(GetMonsterBase(@pMonBase));    if pMonBase = -1 then    begin      form1.RzComboBox1.ItemIndex:= n;      exit;    end;    form1.RzComboBox1.Add('怪物:' + IntToStr(nIndex + 1)) ;    pMonBaseArray[nIndex]:= Pointer;    nIndex:= nIndex + 1;until;form1.RzComboBox1.ItemIndex:= n;end;procedure FreshPlantToolBarList();varnMaxPlant:integer;i:integer;pPlantBase:Pointer;n, nIndex:integer;beginn:= form1.RzComboBox2.ItemIndex;form1.RzComboBox2.Clear;nIndex:= 0;nMaxPlant:= GetMaxPlantNum();for i:= 0 to nMaxPlant - 1 dobegin    pPlantBase:= GetPlantToolbarBase;    pPlantToolBarBaseArray[nIndex]:= pPlantBase;    nIndex:= nIndex + 1;    form1.RzComboBox2.Add('植物栏:' + IntToStr;end;form1.RzComboBox2.ItemIndex:= n;end;procedure TForm1.FormCreate(Sender: TObject);beginGetGameBase();end;procedure FreshPlantList();varpPlantBase:Integer;n, nIndex:integer;beginn:= form1.RzComboBox4.ItemIndex;form1.RzComboBox4.Clear;nIndex:= 0;pPlantBase:= 0;repeat    pPlantBase:= Integer(GetPlantBase(@pPlantBase));    if pPlantBase = -1 then    begin      form1.RzComboBox4.ItemIndex:= n;      exit;    end;    form1.RzComboBox4.Add('植物:' + IntToStr(nIndex + 1)) ;    pPlantBaseArray[nIndex]:= Pointer(pPlantBase);    nIndex:= nIndex + 1;until;end;procedure FreshGoodsList();varpGoodsBase:Integer;cItem:TListItem;n, nIndex:integer;beginn:= form1.RzComboBox3.ItemIndex;form1.RzComboBox3.Clear;nIndex:= 0;pGoodsBase:= 0;repeat    pGoodsBase:= Integer(GetGoodsBase(@pGoodsBase));    if pGoodsBase = -1 then    begin      form1.RzComboBox3.ItemIndex:= n;      exit;    end;    form1.RzComboBox3.Add('物品:' + IntToStr(nIndex + 1)) ;    pGoodsBaseArray[nIndex]:= Pointer(pGoodsBase);    nIndex:= nIndex + 1;until;end;procedure TForm1.TabSheet2Show(Sender: TObject);beginform1.RzComboBox1.Clear;FreshMonsterList();if form1.RzComboBox1.Items.Count > 0 then   form1.RzComboBox1.ItemIndex:= 0;end;procedure TForm1.TabSheet5Show(Sender: TObject);beginFreshGoodsList();if form1.RzComboBox3.Items.Count > 0 thenform1.RzComboBox3.ItemIndex:= 0;end;procedure TForm1.TabSheet4Show(Sender: TObject);beginFreshPlantList();if form1.RzComboBox4.Items.Count > 0 thenform1.RzComboBox4.ItemIndex:= 0;end;procedure SetMonsterInfo(pMonBase:Pointer; stMonInfo:stMonsterInfo);vars:single;begins:= stMonInfo.fSize;asm    pushad    mov eax, pMonBase    mov ecx, stMonInfo.x    mov [eax + $2c], ecx    mov ecx, stMonInfo.y    mov [eax + $30], ecx    mov ecx, stMonInfo.nCurHP    mov [eax + $C8], ecx    mov ecx, stMonInfo.nMaxHP    mov [eax + $cc], ecx    mov ecx, stMonInfo.nRow    mov [eax + $1c], ecx    mov ecx, stMonInfo.fSize    mov [eax + $11c], ecx    popadend;end;procedure GetMonsterInfo(pMonBase:Pointer;stMonInfo:stMonsterInfo);varx:single;y:single;nMaxHP:integer;nCurHP:integer;nRow:integer;fSize:single;beginasm    pushad    mov eax, pMonBase    mov ecx, [eax + $2c]    mov x, ecx    mov ecx, [eax + $30]    mov y, ecx    mov ecx, [eax + $c8]    mov nCurHP, ecx    mov ecx, [eax + $cc]    mov nMaxHP, ecx    mov ecx, [eax + $1c]    mov nRow, ecx    mov ecx, [eax + $11c]    mov fSize, ecx    popadend;form1.RzEdit5.Text:= FloatToStr;form1.RzEdit5.Text:= FloatToStr;form1.RzEdit6.Text:= FloatToStr;form1.RzEdit7.Text:= IntToStr;form1.RzEdit8.Text:= IntToStr;form1.RzEdit9.Text:= IntToStr;form1.RzEdit10.Text:= FloatToStr;end;procedure TForm1.RzButton4Click(Sender: TObject);varpMonBase:Pointer;stInfo:stMonsterInfo;nIndex:integer;beginif form1.RzComboBox1.Items.Count <= 0 then    exit;nIndex:= form1.RzComboBox1.ItemIndex;FreshMonsterList();pMonBase:= Pointer(pMonBaseArray[nIndex]);stInfo.x:= StrToFloat(form1.RzEdit5.Text);stInfo.y:= StrToFloat(form1.RzEdit6.Text);stInfo.nMaxHP:= StrToInt(form1.RzEdit7.Text);stInfo.nCurHP:= StrToInt(form1.RzEdit8.Text);stInfo.nRow:= StrToInt(form1.RzEdit9.Text);stInfo.fSize:= StrToFloat(form1.RzEdit10.Text);nIndex:= form1.RzComboBox1.ItemIndex;FreshMonsterList();pMonBase:= Pointer(pMonBaseArray[nIndex]);SetMonsterInfo(pMonBase, stInfo);end;procedure TForm1.RzComboBox1Change(Sender: TObject);varstInfo:stMonsterInfo;pMonBase:pointer;nIndex:integer;begin   if form1.RzComboBox1.Items.Count <= 0 then    exit;nIndex:= form1.RzComboBox1.ItemIndex;FreshMonsterList();pMonBase:= Pointer(pMonBaseArray[nIndex]);GetMonsterInfo(pMonBase, stInfo);end;procedure TForm1.RzComboBox1CloseUp(Sender: TObject);beginFreshMonsterList();end;procedure SetGoodsInfo(pGoodsBase:Pointer; stInfo:stGoodsInfo);varnType:integer;beginnType:= stInfo.nType;asm    pushad    mov eax, pGoodsBase    mov ecx, nType    mov [eax + $58], ecx    popadend;end;procedure GetGoodsInfo(pGoodsBase:Pointer; var stInfo:stGoodsInfo);varnType:integer;beginasm    pushad    mov eax, pGoodsBase    mov ecx, [eax + $58]    mov nType, ecx    popadend;   form1.RzEdit4.Text:= IntToStr;end;procedure TForm1.TabSheet3Show(Sender: TObject);beginFreshPlantToolBarList();if form1.RzComboBox2.Items.Count > 0 then    form1.RzComboBox2.ItemIndex:= 0;end;procedure TForm1.RzComboBox3Change(Sender: TObject);varstInfo:stGoodsInfo;pGoodsBase:pointer;nIndex:integer;begin   if form1.RzComboBox3.Items.Count <= 0 then    exit;nIndex:= form1.RzComboBox3.ItemIndex;FreshGoodsList();pGoodsBase:= Pointer(pGoodsBaseArray[nIndex]);GetGoodsInfo(pGoodsBase, stInfo);end;procedure TForm1.RzButton3Click(Sender: TObject);varstInfo:stGoodsInfo;nIndex:integer;pGoodsBase:Pointer;begin    if (form1.RzComboBox3.Items.Count <= 0) and (StrToInt(form1.RzEdit4.Text) <= 15) then    exit;nIndex:= form1.RzComboBox3.ItemIndex;FreshGoodsList();pGoodsBase:= Pointer(pGoodsBaseArray[nIndex]);// ShowMessage(IntToStr(DWORD(pGoodsBase)));stInfo.nType:= StrToInt(form1.RzEdit4.Text);SetGoodsInfo(pGoodsBase, stInfo);end;procedure GetPlantInfo(pPlantBase:Pointer; var stInfo:stPlantInfo);varbIsProdure:integer;nType:integer;beginasm    pushad    mov eax, pPlantBase    mov ecx, [eax + $28]    mov bIsProdure, ecx    mov ecx, [eax + $24]    mov nType, ecx    popadend;   form1.RzEdit3.Text:= IntToStr(bIsProdure);   form1.RzEdit2.Text:= IntToStr;end;procedure SetPlantInfo(pPlantBase:Pointer; stInfo:stPlantInfo);varbIsProdure:integer;nType:integer;beginbIsProdure:= stInfo.bIsProdure;nType:= stInfo.nType;asm    pushad    mov eax, pPlantBase    mov ecx, bIsProdure    mov [eax + $24], ecx    mov ecx, nType    mov [eax + $28], ecx    popadend;end;procedure TForm1.RzComboBox4Change(Sender: TObject);varstInfo:stPlantInfo;pPlantBase:pointer;nIndex:integer;beginif form1.RzComboBox4.Items.Count <= 0 then    exit;nIndex:= form1.RzComboBox4.ItemIndex;FreshPlantList();pPlantBase:= Pointer(pPlantBaseArray[nIndex]);GetPlantInfo(pPlantBase, stInfo);end;procedure TForm1.RzButton2Click(Sender: TObject);varstInfo:stPlantInfo;nIndex:integer;pPlantBase:Pointer;beginif (MessageBox(form1.Handle, '该功能可能会引起不良效果,请确定要不要使用?使用前请先保存游戏!!', '提示', Windows.MB_ICONWARNING or MB_YESNO) = IDNO) then    exit;if (form1.RzComboBox4.Items.Count <= 0) then    exit;nIndex:= form1.RzComboBox4.ItemIndex;FreshPlantList();pPlantBase:= Pointer(pPlantBaseArray[nIndex]);// ShowMessage(IntToStr(DWORD(pGoodsBase)));stInfo.bIsProdure:= StrToInt(form1.RzEdit3.Text);stInfo.nType:= StrToInt(form1.RzEdit2.Text);SetPlantInfo(pPlantBase, stInfo);end;procedure TForm1.RzComboBox4CloseUp(Sender: TObject);beginFreshPlantList(); end;procedure GetPlantToolBarInfo(pPlantBase:Pointer; var stInfo:stPlantToolBarInfo);varnType:integer;nMaxRecovery:integer;nCurRecovery:integer;beginasm    pushad    mov eax, pPlantBase    mov ecx, [eax + $34]    mov nType, ecx    mov ecx, [eax + $24]    mov nCurRecovery, ecx    mov ecx, [eax + $28]    mov nMaxRecovery, ecx    popadend;   form1.RzEdit1.Text:= IntToStr;   form1.RzEdit11.Text:= IntToStr(nCurRecovery);   form1.RzEdit12.Text:= IntToStr(nMaxRecovery);end;procedure SetPlantToolBarInfo(pPlantBase:Pointer; var stInfo:stPlantToolBarInfo);varnType:integer;nMaxRecovery:integer;nCurRecovery:integer;beginnType:= stInfo.nType;   nMaxRecovery:= stInfo.nMaxRecovery;nCurRecovery:= stInfo.nCurRecovery;asm    pushad    mov eax, pPlantBase    mov ecx, nType    mov [eax + $34], ecx    mov ecx, nMaxRecovery    mov [eax + $28], ecx    mov ecx, nCurRecovery    mov [eax + $24], ecx    popadend;end;procedure TForm1.RzComboBox2Change(Sender: TObject);varstInfo:stPlantToolBarInfo;pPlantToolBarBase:pointer;nIndex:integer;beginif form1.RzComboBox2.Items.Count <= 0 then    exit;nIndex:= form1.RzComboBox2.ItemIndex;FreshPlantToolBarList();pPlantToolBarBase:= Pointer(pPlantToolBarBaseArray[nIndex]);GetPlantToolBarInfo(pPlantToolBarBase, stInfo);end;procedure TForm1.RzButton1Click(Sender: TObject);varstInfo:stPlantToolBarInfo;nIndex:integer;pPlantToolBarBase:Pointer;beginif (form1.RzComboBox2.Items.Count <= 0) then    exit;nIndex:= form1.RzComboBox2.ItemIndex;FreshPlantToolBarList();pPlantToolBarBase:= Pointer(pPlantToolBarBaseArray[nIndex]);// ShowMessage(IntToStr(DWORD(pGoodsBase)));stInfo.nType:= StrToInt(form1.RzEdit1.Text);stInfo.nMaxRecovery:= StrToInt(form1.RzEdit12.Text);stInfo.nCurRecovery:= StrToInt(form1.RzEdit11.Text);SetPlantToolBarInfo(pPlantToolBarBase, stInfo);end;procedure TForm1.RzButton6Click(Sender: TObject);varnPlantToolBarNum:integer;beginasm    pushad    mov eax, pGameBase    mov eax, [eax + $144]    add eax, $24    mov ecx, 9    mov [eax], ecx    popadendend;procedure TForm1.RzButton5Click(Sender: TObject);beginasmpushadmov eax, pGameBaseadd eax, $5560mov [eax], 9999999popadend;end;procedure TForm1.RzComboBox3CloseUp(Sender: TObject);beginFreshGoodsList(); end;procedure TForm1.RzComboBox2CloseUp(Sender: TObject);beginFreshPlantToolBarList(); end;function WriteMemory(szProcName:PChar; pAddr:Pointer; szBuf:array of char; dwSize:DWORD):boolean;varhGameWnd:HWND;dwID:DWORD;hProc:THandle;dwWriteByte:DWORD;beginhGameWnd:= FindWindow(nil, szProcName);GetWindowThreadProcessId(hGameWnd, dwID);hProc:= OpenProcess(PROCESS_ALL_ACCESS, false, dwID);if hProc = 0 then    begin    Result:= false;    exit;    end;WriteProcessMemory(hProc, pAddr, @szBuf, dwSize, dwWriteByte);CloseHandle;Result:= true;end;procedure ModiryPlantToolBar();varnMaxPlant:integer;i:integer;pPlantBase:Pointer;n, nIndex:integer;beginnIndex:= 0;nMaxPlant:= GetMaxPlantNum();for i:= 0 to nMaxPlant - 1 dobegin    pPlantBase:= GetPlantToolbarBase;    asm      pushad      mov eax, pPlantBase      mov [eax + $28], 0      popad    end;    nIndex:= nIndex + 1;end;end;procedure TForm1.RzButton7Click(Sender: TObject);varszBuf:array[0..2] of char;beginszBuf[0]:= Char($90);szBuf[1]:= Char($90);szBuf[2]:= Char($90);WriteMemory('植物大战僵尸中文版', Pointer, szBuf, 3);ModiryPlantToolBar();asmpushadmov eax, pGameBaseadd eax, $5560mov [eax], 9999999popadend;end;procedure GrowPlant(x,y,nType:integer);beginasm    pushad    mov eax, y    push -1    push nType    push x    push pGameBase    mov edi, $0040D120    call edi    popadend;end;procedure TForm1.RzButton8Click(Sender: TObject);varx,y:integer;nType:integer;n:integer;beginrandomize;nType:= 0;n:= 0;for x:= 0 to 8 dobegin    for y:= 0 to 5 do    begin    if RzComboBox5.ItemIndex = 0 then      nType:= math.RandomRange(0, 48)    else if RzComboBox5.ItemIndex = 1 then    begin      nType:= n;      n:= n + 1;      if n = 48 then      n:= 0;    end    else      nType:= RzComboBox5.ItemIndex - 2;      GrowPlant(x, y, nType);    end;end;end;procedure TForm1.TabSheet1Show(Sender: TObject);vari:integer;beginRzComboBox5.Add('随机种植');RzComboBox5.Add('顺序种植');for i:= 1 to 48 do    RzComboBox5.Add(IntToStr;        RzComboBox5.ItemIndex:= 0;end;procedure TForm1.TabSheet1MouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);beginGetGameBase();end;procedure TForm1.RzButton9Click(Sender: TObject);varszBuf:array[0..3] of char;beginszBuf[0]:= Char($90);szBuf[1]:= Char($90);szBuf[2]:= Char($90);szBuf[3]:= Char($90);WriteMemory('植物大战僵尸中文版', Pointer, szBuf, 4);end;procedure KillAllMonster();varpMonBase:Integer;n, nIndex:integer;stInfo:stMonsterInfo;beginnIndex:= 0;pMonBase:= 0;repeat    pMonBase:= Integer(GetMonsterBase(@pMonBase));    if pMonBase = -1 then    begin      exit;    end;    asm    pushad    mov eax, pMonBase    mov [eax + $c8], -1    popad    end;until;end;procedure TForm1.RzButton10Click(Sender: TObject);beginShowMessage('由于种种原因,怪物需要再K它一下,O(∩_∩)O哈哈~');KillAllMonster();end;end.

004040FF > 60 PUSHAD
00404100 68 54404000 PUSH AHpack.00404054 ; ASCII "KERNEL32.DLL"
00404105 B8 48404000 MOV EAX,<&KERNEL32.GetModuleHandleA>
0040410A FF10 CALL DWORD PTR DS:[EAX] ; 获得kernerl32基地址
0040410C 68 B3404000 PUSH AHpack.004040B3 ; ASCII "GlobalAlloc"
00404111 50 PUSH EAX
00404112 B8 44404000 MOV EAX,<&KERNEL32.GetProcAddress>
00404117 FF10 CALL DWORD PTR DS:[EAX] ; 从kernel32里获取GlobalAlloc函数
00404119 68 00080000 PUSH 800
0040411E 6A 40 PUSH 40 ; GPTR
00404120 FFD0 CALL EAX ; 申请800字节
00404122 8905 CA404000 MOV DWORD PTR DS:[4040CA],EAX
00404128 89C7 MOV EDI,EAX
0040412A BE 00104000 MOV ESI,AHpack.00401000
0040412F 60 PUSHAD ; 开始aplib
00404130 FC CLD
00404131 B2 80 MOV DL,80
00404133 31DB XOR EBX,EBX
00404135 A4 MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] 
00404136 B3 02 MOV BL,2
00404138 E8 6D000000 CALL AHpack.004041AA
0040413D ^ 73 F6 JNB SHORT AHpack.00404135
0040413F 31C9 XOR ECX,ECX
00404141 E8 64000000 CALL AHpack.004041AA
00404146 73 1C JNB SHORT AHpack.00404164
00404148 31C0 XOR EAX,EAX
0040414A E8 5B000000 CALL AHpack.004041AA
0040414F 73 23 JNB SHORT AHpack.00404174
00404151 B3 02 MOV BL,2
00404153 41 INC ECX
00404154 B0 10 MOV AL,10
00404156 E8 4F000000 CALL AHpack.004041AA
0040415B 10C0 ADC AL,AL
0040415D ^ 73 F7 JNB SHORT AHpack.00404156
0040415F 75 3F JNZ SHORT AHpack.004041A0
00404161 AA STOS BYTE PTR ES:[EDI]
00404162 ^ EB D4 JMP SHORT AHpack.00404138
00404164 E8 4D000000 CALL AHpack.004041B6
00404169 29D9 SUB ECX,EBX
0040416B 75 10 JNZ SHORT AHpack.0040417D
0040416D E8 42000000 CALL AHpack.004041B4
00404172 EB 28 JMP SHORT AHpack.0040419C
00404174 AC LODS BYTE PTR DS:[ESI]
00404175 D1E8 SHR EAX,1
00404177 74 4D JE SHORT AHpack.004041C6
00404179 11C9 ADC ECX,ECX
0040417B EB 1C JMP SHORT AHpack.00404199
0040417D 91 XCHG EAX,ECX
0040417E 48 DEC EAX
0040417F C1E0 08 SHL EAX,8
00404182 AC LODS BYTE PTR DS:[ESI]
00404183 E8 2C000000 CALL AHpack.004041B4
00404188 3D 007D0000 CMP EAX,7D00
0040418D 73 0A JNB SHORT AHpack.00404199
0040418F 80FC 05 CMP AH,5
00404192 73 06 JNB SHORT AHpack.0040419A
00404194 83F8 7F CMP EAX,7F
00404197 77 02 JA SHORT AHpack.0040419B
00404199 41 INC ECX
0040419A 41 INC ECX
0040419B 95 XCHG EAX,EBP
0040419C 89E8 MOV EAX,EBP
0040419E B3 01 MOV BL,1
004041A0 56 PUSH ESI
004041A1 89FE MOV ESI,EDI
004041A3 29C6 SUB ESI,EAX
004041A5 F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>
004041A7 5E POP ESI
004041A8 ^ EB 8E JMP SHORT AHpack.00404138
004041AA 00D2 ADD DL,DL
004041AC 75 05 JNZ SHORT AHpack.004041B3
004041AE 8A16 MOV DL,BYTE PTR DS:[ESI]
004041B0 46 INC ESI
004041B1 10D2 ADC DL,DL
004041B3 C3 RETN
004041B4 31C9 XOR ECX,ECX
004041B6 41 INC ECX
004041B7 E8 EEFFFFFF CALL AHpack.004041AA
004041BC 11C9 ADC ECX,ECX
004041BE E8 E7FFFFFF CALL AHpack.004041AA
004041C3 ^ 72 F2 JB SHORT AHpack.004041B7
004041C5 C3 RETN
004041C6 61 POPAD ; 甘休aplib,数据解到404120处申请的内存中
004041C7 B9 FC070000 MOV ECX,7FC
004041CC 8B1C08 MOV EBX,DWORD PTR DS:[EAX+ECX]
004041CF 8999 00104000 MOV DWORD PTR DS:[ECX+401000],EBX
004041D5 ^ E2 F5 LOOPD SHORT AHpack.004041CC ; 404120处申请的内部存款和储蓄器满含解压后数据,把它拷贝到oep处
004041D7 90 NOP ; 上面发轫修复IAT,呵呵,9090不会是明知故犯给个分叉吧
004041D8 90 NOP
004041D9 BA 00004000 MOV EDX,AHpack.00400000
004041DE BE 70200000 MOV ESI,2070
004041E3 01D6 ADD ESI,EDX ; esi用来迭代IMAGE_IMPORT_DESC昂CoraIPTOLX570,esi以后开头化为指向第一个IMAGE_IMPORT_DESCRIPTOR的指针
004041E5 8B46 0C MOV EAX,DWORD PTR DS:[ESI+C] ; eax指向要修复的dll名
004041E8 85C0 TEST EAX,EAX
004041EA 0F84 8九千000 JE AHpack.00404277 ; 假设一切修复完结就跳转
004041F0 01D0 ADD EAX,EDX
004041F2 89C3 MOV EBX,EAX
004041F4 50 PUSH EAX
004041F5 B8 48404000 MOV EAX,<&KERNEL32.GetModuleHandleA>
004041FA FF10 CALL DWORD PTR DS:[EAX] ; 获取要修复dll的集散地址
004041FC 85C0 TEST EAX,EAX
004041FE 75 08 JNZ SHORT AHpack.00404208 ; 即便获得战败,就加载二回
00404200 53 PUSH EBX
00404201 B8 4C404000 MOV EAX,<&KERNEL32.LoadLibraryA>
00404206 FF10 CALL DWORD PTR DS:[EAX]
00404208 8905 CE404000 MOV DWORD PTR DS:[4040CE],EAX ; 要修复dll基址存到4040CE
0040420E C705 D2404000 0>MOV DWORD PTR DS:[4040D2],0 ; 4040D2用来描述此dll已经修复的个数,[4040D2]/4=已修复个数
00404218 BA 00004000 MOV EDX,AHpack.00400000
0040421D 8B06 MOV EAX,DWORD PTR DS:[ESI]
0040421F 85C0 TEST EAX,EAX
00404221 75 03 JNZ SHORT AHpack.00404226
00404223 8B46 10 MOV EAX,DWORD PTR DS:[ESI+10]
00404226 01D0 ADD EAX,EDX ; 基地址加IAT的舞狮
00404228 0305 D2404000 ADD EAX,DWORD PTR DS:[4040D2] ; 再加修复次数*4
0040422E 8B18 MOV EBX,DWORD PTR DS:[EAX] ; [eax]指向IMPORT_BY_NAME
00404230 8B7E 10 MOV EDI,DWORD PTR DS:[ESI+10]
00404233 01D7 ADD EDI,EDX
00404235 033D D2404000 ADD EDI,DWORD PTR DS:[4040D2]
0040423B 85DB TEST EBX,EBX
0040423D 74 2B JE SHORT AHpack.0040426A ; 假使这几个dll已经修复完则跳转
0040423F F7C3 00000080 TEST EBX,80000000 ; 剖断下是还是不是取错数据
00404245 75 04 JNZ SHORT AHpack.0040424B
00404247 01D3 ADD EBX,EDX
00404249 43 INC EBX ; 因为第四个字段占三个word,所以一遍inc是为着访谈IMPORT_BY_NAME.Name
0040424A 43 INC EBX
0040424B 81E3 FFFFFF0F AND EBX,0FFFFFFF ; 前4位清零
00404251 53 PUSH EBX ; 要修复函数名
00404252 FF35 CE404000 PUSH DWORD PTR DS:[4040CE] ; 要修复函数所在的dll
00404258 B8 44404000 MOV EAX,<&KERNEL32.GetProcAddress>
0040425D FF10 CALL DWORD PTR DS:[EAX] ; 使用GetProcAddress把精确地址收取来
0040425F 8907 MOV DWORD PTR DS:[EDI],EAX ; 修复IAT
00404261 8305 D2404000 0>ADD DWORD PTR DS:[4040D2],4 ; 已修复个数+1
00404268 ^ EB AE JMP SHORT AHpack.00404218 ; 跳上去继续修补下三个函数
0040426A 83C6 14 ADD ESI,14 ; 0x14为IMAGE_IMPORT_DESC科雷傲IPTO奥德赛大小,继续迭代到下个dll
0040426D BA 00005000 MOV EDX,AHpack.00五千00 ; 这步是多余操作
00404272 ^ E9 6EFFFFFF JMP AHpack.004041E5 ; 跳上去继续修补下二个dll
00404277 68 54404000 PUSH AHpack.00404054 ; ASCII "KERNEL32.DLL"
0040427C B8 48404000 MOV EAX,<&KERNEL32.GetModuleHandleA>
00404281 FF10 CALL DWORD PTR DS:[EAX] ; 获得kernel32基地址
00404283 68 BF404000 PUSH AHpack.004040BF ; ASCII "GlobalFree"
00404288 50 PUSH EAX
00404289 B8 44404000 MOV EAX,<&KERNEL32.GetProcAddress>
0040428E FF10 CALL DWORD PTR DS:[EAX] ; 从kernel32取GlobalFree()
00404290 8B15 CA404000 MOV EDX,DWORD PTR DS:[4040CA]
00404296 52 PUSH EDX
00404297 FFD0 CALL EAX ; 释放在此以前申请的buffer
00404299 61 POPAD
0040429A BA 00104000 MOV EDX,AHpack.00401000
0040429F FFE2 JMP EDX ; 跳oep
004042A1 90 NOP
004042A2 C3 RETN

以上分析中,木色的数目经过《植物大战尸鬼中文第二版》测量试验通过。

qq1454322323


年度版:

阳光: [[7794F8]+868]+5578

植株冷却状态地址(0为不可用,1为可用):
第1格: [[[7794F8]+868]+15C]+70
第2格: [[[7794F8]+868]+15C]+C0
第3格: [[[7794F8]+868]+15C]+110
第4格: [[[7794F8]+868]+15C]+160
第5格: [[[7794F8]+868]+15C]+1B0
第6格: [[[7794F8]+868]+15C]+200
第7格: [[[7794F8]+868]+15C]+250
第8格: [[[7794F8]+868]+15C]+2A0
第9格: [[[7794F8]+868]+15C]+2F0
第10格: [[[7794F8]+868]+15C]+340

编辑: 操作系统 本文来源:逆向深入分析AHpack,植物战役活死人汉语第二版

关键词: