二进制文件
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s; // [rsp+0h] [rbp-20h]
int v5; // [rsp+18h] [rbp-8h]
int i; // [rsp+1Ch] [rbp-4h]
for ( i = 0; i <= 181; ++i )
{
envp = (const char **)(*((unsigned __int8 *)judge + i) ^ 0xCu);
*((_BYTE *)judge + i) ^= 0xCu;
}
printf("Please input flag:", argv, envp);
__isoc99_scanf("%20s", &s);
v5 = strlen(&s);
if ( v5 == 14 && (unsigned int)judge(&s) )//输入长度为14的字符串,judge()这个应该是函数?
//但在IDA中打不开
puts("Right!");
else
puts("Wrong!");
return 0;
}
看一下汇编怎么说
.text:0000000000400637
.text:0000000000400637 loc_400637:
.text:0000000000400637 cmp [rbp+var_4], 0B5h;b5=181
.text:000000000040063E jle short loc_4
.text:0000000000400640 mov edi, offset format ; "Please input flag:"
;绕过182次循环,直接在这里下断点
.text:0000000000400645 mov eax, 0
.text:000000000040064A call _printf
.text:000000000040064F lea rax, [rbp+s]
.text:0000000000400653 mov rsi, rax
.text:0000000000400656 mov edi, offset a20s ; "%20s"
.text:000000000040065B mov eax, 0
.text:0000000000400660 call ___isoc99_scanf
.text:0000000000400665 lea rax, [rbp+s]
.text:0000000000400669 mov rdi, rax ; s
.text:000000000040066C call _strlen
.text:0000000000400671 mov [rbp+var_8], eax
.text:0000000000400674 cmp [rbp+var_8], 0Eh;字符串长度14
.text:0000000000400678 jnz short loc_40
.text:000000000040067A mov edx, offset judge;将judge偏移地址存进edx
.text:000000000040067F lea rax, [rbp+s]
.text:0000000000400683 mov rdi, rax;将段地址存进rdi
.text:0000000000400686 call rdx ; judge ;运行judge函数,关注rdx的值
.text:0000000000400688 test eax, eax
.text:000000000040068A jz short loc_4
.text:000000000040068C mov edi, offset s ; "Right!"
.text:0000000000400691 call _puts
.text:0000000000400696 jmp short loc_4006A2
虚拟机开起来
gdb babyre
b *(0x400640) ;下断点跳过循环
r ;运行至断点处
n ;步过
► 0x400686 <main+128> call rdx <judge>
rdi: 0x7fffffffdd20 ◂— '77777777777777'
rsi: 0x1
rdx: 0x600b00 (judge) ◂— 0xd87d8948e5894855
rcx: 0xd20
0x400688 <main+130> test eax, eax
0x40068a <main+132> je main+146 <main+146>
s ;步入函数
0x600b01 <judge+1> mov rbp, rsp
0x600b04 <judge+4> mov qword ptr [rbp - 0x28], rdi
0x600b08 <judge+8> mov byte ptr [rbp - 0x20], 0x66
0x600b0c <judge+12> mov byte ptr [rbp - 0x1f], 0x6d
0x600b10 <judge+16> mov byte ptr [rbp - 0x1e], 0x63
► 0x600b14 <judge+20> mov byte ptr [rbp - 0x1d], 0x64
0x600b18 <judge+24> mov byte ptr [rbp - 0x1c], 0x7f
0x600b1c <judge+28> mov byte ptr [rbp - 0x1b], 0x6b
0x600b20 <judge+32> mov byte ptr [rbp - 0x1a], 0x37
0x600b24 <judge+36> mov byte ptr [rbp - 0x19], 0x64
0x600b28 <judge+40> mov byte ptr [rbp - 0x18], 0x3b
0x600b2c <judge+44> mov byte ptr [rbp - 0x17], 0x56
► 0x600b30 <judge+48> mov byte ptr [rbp - 0x16], 0x60
0x600b34 <judge+52> mov byte ptr [rbp - 0x15], 0x3b
0x600b38 <judge+56> mov byte ptr [rbp - 0x14], 0x6e
0x600b3c <judge+60> mov byte ptr [rbp - 0x13], 0x70
0x600b40 <judge+64> mov dword ptr [rbp - 4], 0
进入函数后看到一串赋值,且刚好长度为14,但不是输入jjjjjj…,所以可能这就是judge中存的flag。
66 6d 63 64 7f 6b 37 64 3b 56 60 3b 6e 70
但拿去转成字符串发现是一串乱码pn;`V;d7k(小三角)dcmf,好吧不是flag,再继续看看
0x600b40 <judge+64> mov dword ptr [rbp - 4], 0;[rbp - 4]=0
0x600b47 <judge+71> jmp judge+113 <judge+113>
↓
► 0x600b71 <judge+113> cmp dword ptr [rbp - 4], 0xd
;从0开始循环至13,一共14次,可能下面这个循环是转化函数
0x600b75 <judge+117> jle judge+73 <judge+73>
↓
0x600b49 <judge+73> mov eax, dword ptr [rbp - 4];eax=0
0x600b4c <judge+76> movsxd rdx, eax;rdx=0
0x600b4f <judge+79> mov rax, qword ptr [rbp - 0x28];rax=输入的字符串
0x600b53 <judge+83> add rax, rdx;rax[0]='j'
0x600b56 <judge+86> mov edx, dword ptr [rbp - 4];edx=0
0x600b59 <judge+89> movsxd rcx, edx;rcx=0
0x600b5c <judge+92> mov rdx, qword ptr [rbp - 0x28];rdx=输入的字符串
0x600b60 <judge+96> add rdx, rcx;rdx[0]='j'
0x600b63 <judge+99> movzx edx, byte ptr [rdx];edx[0]=0x6a
► 0x600b66 <judge+102> mov ecx, dword ptr [rbp - 4];ecx=0
0x600b69 <judge+105> xor edx, ecx;edx与ecx异或,0x6a^0=0x6a
0x600b6b <judge+107> mov byte ptr [rax], dl;rax[0]=6a
0x600b6d <judge+109> add dword ptr [rbp - 4], 1;[rbp-4]=1
0x600b71 <judge+113> cmp dword ptr [rbp - 4], 0xd;与13相比
0x600b75 <judge+117> jle judge+73 <judge+73>
↓
0x600b49 <judge+73> mov eax, dword ptr [rbp - 4];eax=1
0x600b4c <judge+76> movsxd rdx, eax;rdx=1
0x600b4f <judge+79> mov rax, qword ptr [rbp - 0x28];rax=输入的字符串
► 0x600b53 <judge+83> add rax, rdx;rax[1]='j'
0x600b56 <judge+86> mov edx, dword ptr [rbp - 4];edx=1
0x600b59 <judge+89> movsxd rcx, edx;rcx=1
0x600b5c <judge+92> mov rdx, qword ptr [rbp - 0x28];rdx=输入的字符串
0x600b60 <judge+96> add rdx, rcx;rdx[1]='j'
0x600b63 <judge+99> movzx edx, byte ptr [rdx];edx[1]=0x6a
0x600b66 <judge+102> mov ecx, dword ptr [rbp - 4];ecx=1
0x600b69 <judge+105> xor edx, ecx;edx与ecx异或,0x6a^1=0x6b
0x600b6b <judge+107> mov byte ptr [rax], dl;rax[1]=6b
0x600b6d <judge+109> add dword ptr [rbp - 4], 1;[rbp-4]=2
0x600b71 <judge+113> cmp dword ptr [rbp - 4], 0xd;与13相比
0x600b75 <judge+117> jle judge+73 <judge+73>
exp
int flag[14]={0};
int judge[14]={0x66, 0x6d, 0x63, 0x64, 0x7f, 0x6b, 0x37, 0x64, 0x3b, 0x56, 0x60, 0x3b, 0x6e, 0x70};
int i;
for(i=0; i<14; i++)
{
judge[i] = judge[i]^i;
printf("%c",(char)flag[i]);
}
//flag{n1c3_j0b}