[Pwnable.kr] dragon
略需要逆向的一道题,是一个打怪兽的小游戏。首先F5看一下代码(只贴关键部分)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
int __cdecl main(int argc, const char **argv, const char **envp) { setvbuf(stdout, 0, 2, 0); setvbuf(stdin, 0, 2, 0); puts("Welcome to Dragon Hunter!"); PlayGame(); return 0; } int PlayGame() { int result; // eax@1 while ( 1 ) { while ( 1 ) { puts("Choose Your Hero\n[ 1 ] Priest\n[ 2 ] Knight"); result = GetChoice(); if ( result != 1 && result != 2 ) break; FightDragon(result); } if ( result != 3 ) break; SecretLevel(); } return result; } void __cdecl FightDragon(int a1) { char v1; // al@1 void *v2; // ST1C_4@10 int v3; // [esp+10h] [ebp-18h]@7 _DWORD *ptr; // [esp+14h] [ebp-14h]@1 _DWORD *v5; // [esp+18h] [ebp-10h]@1 ptr = malloc(0x10u); v5 = malloc(0x10u); v1 = Count++; if ( v1 & 1 ) { v5[1] = 1; *((_BYTE *)v5 + 8) = 80; *((_BYTE *)v5 + 9) = 4; v5[3] = 10; *v5 = PrintMonsterInfo; puts("Mama Dragon Has Appeared!"); } else { v5[1] = 0; *((_BYTE *)v5 + 8) = 50; *((_BYTE *)v5 + 9) = 5; v5[3] = 30; *v5 = PrintMonsterInfo; puts("Baby Dragon Has Appeared!"); } if ( a1 == 1 ) { *ptr = 1; ptr[1] = 42; ptr[2] = 50; ptr[3] = PrintPlayerInfo; v3 = PriestAttack((int)ptr, v5); } else { if ( a1 != 2 ) return; *ptr = 2; ptr[1] = 50; ptr[2] = 0; ptr[3] = PrintPlayerInfo; v3 = KnightAttack((int)ptr, v5); } if ( v3 ) { puts("Well Done Hero! You Killed The Dragon!"); puts("The World Will Remember You As:"); v2 = malloc(0x10u); __isoc99_scanf("%16s", v2); puts("And The Dragon You Have Defeated Was Called:"); ((void (__cdecl *)(_DWORD *))*v5)(v5); } else { puts("\nYou Have Been Defeated!"); } free(ptr); } int __cdecl PriestAttack(int a1, void *ptr) { int v2; // eax@1 do { (*(void (__cdecl **)(void *))ptr)(ptr); (*(void (__cdecl **)(int))(a1 + 12))(a1); v2 = GetChoice(); switch ( v2 ) { case 2: puts("Clarity! Your Mana Has Been Refreshed"); *(_DWORD *)(a1 + 8) = 50; printf("But The Dragon Deals %d Damage To You!\n", *((_DWORD *)ptr + 3)); *(_DWORD *)(a1 + 4) -= *((_DWORD *)ptr + 3); printf("And The Dragon Heals %d HP!\n", *((char *)ptr + 9)); *((_BYTE *)ptr + 8) += *((_BYTE *)ptr + 9); break; case 3: if ( *(_DWORD *)(a1 + 8) <= 24 ) { puts("Not Enough MP!"); } else { puts("HolyShield! You Are Temporarily Invincible..."); printf("But The Dragon Heals %d HP!\n", *((char *)ptr + 9)); *((_BYTE *)ptr + 8) += *((_BYTE *)ptr |