###### tags: `程安`
# CS 2019 Fall - Homework 0x02
### [0x02] IDAmudamudamuda
一樣 IDA 起手式
```cpp=
int __cdecl main(int argc, const char **argv, const char **envp)
{
int input_seed; // [esp+0h] [ebp-2Ch]
char input_flag; // [esp+4h] [ebp-28h]
sub_D71000();
puts("Oh, it's another ez Reversing Challenge");
puts("Leverage all you learned in class to solve this one");
puts("2 step to get the flag: \n\n\n");
puts("First, give me the seed: ");
scanf("%d", &input_seed);
sub_D71070(input_seed);
puts("\n\n\nOK then whats the flag ?");
scanf("%s", &input_flag);
if ( sub_D71270(&input_flag) )
{
puts("OH yeah, you got the flag\n\n\n");
}
else
{
puts("That's not right,"
" go back to review the slides on https://edu-ctf.csie.org");
puts("Hint: file format, calling convention,"
" shellcode, stack frame !!\n\n\n\n");
}
system("pause");
return 0;
}
```
我們來看一下關鍵的 3 個部份︰
* `sub_D71000()`
* `sub_D71070(input_seed)`
* `sub_D71270(&input_flag)`
--- **Part 1**
```cpp=
FARPROC sub_D71000()
{
HMODULE v0; // eax
FARPROC result; // eax
HMODULE hModule; // [esp+4h] [ebp-4h]
hModule = LoadLibraryA("msvcrt.dll");
puts = GetProcAddress(hModule, "puts");
scanf = GetProcAddress(hModule, "scanf");
v0 = LoadLibraryA("Kernel32.dll");
result = GetProcAddress(v0, "GetModuleHandleA");
GetModuleHandleA = result;
return result;
}
```
這邊的重點在於
```cpp=11
result = GetProcAddress(v0, "GetModuleHandleA");
GetModuleHandleA = result;
```
--- **Part 2**
```cpp=
int __cdecl sub_D71070(char input_int)
{
char *handle; // eax
int result; // eax
int v3; // [esp+4h] [ebp-28h]
char *v4; // [esp+8h] [ebp-24h]
int m; // [esp+14h] [ebp-18h]
int i; // [esp+18h] [ebp-14h]
int k; // [esp+1Ch] [ebp-10h]
int handle_var_2; // [esp+20h] [ebp-Ch]
int j; // [esp+24h] [ebp-8h]
int l; // [esp+24h] [ebp-8h]
handle = GetModuleHandleA(0);
handle_var = handle;
result = *handle;
if ( result == 'M' )
{
result = *(handle_var + 1);
if ( result == 'Z' )
{
v4 = (*(handle_var + 60) + handle_var);
result = *v4
if ( result == 'P' )
{
result = v4[1];
if ( result == 'E' )
{
for ( i = (v4 + 248); ; i += 40 )
{
v3 = strcmp(i, ".data");
if ( v3 )
v3 = v3 < 0 ? -1 : 1;
if ( !v3 )
break;
}
handle_var_2 = *(i + 12) + handle_var;
for ( j = 0; ; ++j )
{
result = i;
if ( j >= *(i + 8) )
break;
result = *(j + handle_var_2);
if ( result == 15 )
{
for ( k = 0; k < 32; ++k )
{
result = j + handle_var_2;
*(j + handle_var_2 + k) += *(j + handle_var_2 + k + 32);
}
break;
}
}
for ( l = j + 33; l < *(i + 8); ++l )
{
if ( *(l + handle_var_2) == 69 )
{
for ( m = 0; ; ++m )
{
result = l + handle_var_2;
if ( !*(l + handle_var_2 + m) )
break;
*(l + handle_var_2 + m) += input_int;
}
return result;
}
result = l + 1;
}
}
}
}
}
return result;
}
```
這部份有點長
簡單來說,就是他靠 **Part 1** 那個 function 來拿到自己這個 process 的當前位置,然後對`.data`的某個位置做與我們 input 進去的`seed`有關的計算 (第63行)
--- **Part 3**
```cpp=
int __cdecl sub_D71270(const char *input_str)
{
void *v2; // eax
if ( strlen(input_str) != 32 )
return 0;
v2 = VirtualAlloc(0, 0xC8u, 0x1000u, 0x40u);
qmemcpy(v2, &source_str, 0xC8u);
return (v2)(input_str, &unk_D74018);
}
```
這邊我們可以先簡單看出 FLAG 長度為 32,後面則是將一段未知內容的字串`source_str` copy 到`v2`,然後`v2`把當作 function 去 call 他,並把我們 input 的字串跟一個未知的字串當作參數傳給他
既然`v2`的位置是動態要出來的,我們就只能用 x64dbg 來動態一下
--- **Part 4**
我們先輸入`seed=0`和`flag="12341234123412341234123412341234"`
我們先找到`v2`的位置

我們繼續跟下去

長的完全不像一個 function (例如最後結尾不是`pop ebp; ret`之類的)
我們換成`seed=1`試試看

內容果然變了,而且每個 byte 都跟`seed=0`的時候差 1。
也就是說,在 **Part 2** 中`.data`的某個位置被做了與`seed`有關的計算,其實就是在更改這個部份
那既然這個字串應該要長的像一個 function,那我們就大膽猜測最後一個 byte 應該要是`c3 (ret)`,也就是`seed=16`

看起來是猜中了,我們再來借助一下 IDA 的 decompiler 吧
```cpp=
int __cdecl sub_8F0000(int input_str, int arg2)
{
int i; // [esp+0h] [ebp-4h]
for ( i = 0; *(i + arg2); ++i )
{
if ( ((*(i + input_str) + 35) ^ 102) != *(i + arg2) )
return 0;
}
return 1;
}
```
這個 function 其實就是一個 flag checker,將我們 input 的字串每個 byte `+ 35`再`& 102`之後與`arg2`做比對,也就是說我們直接將`(arg[i] ^ 102) - 35`即為 flag
那`arg2`再哪呢?我們在 **Part 3** 時可以看到
```cpp=9
return (v2)(input_str, &unk_D74018);
```
`unk_D74018`即為`arg2`

`unk_D74018 = "\x0F\x09\x02\x0C ... \x22\x22\xC6\x00"`
然後我們寫個簡單的 script 就可以拿到 flag 了
:::success
FLAG{y3s!!y3s!!y3s!!0h_my_g0d!!}
:::