参考wpRE套路/从EASYHOOK学inline hook - c10udlnk - 博客园
题目下载:下载
这是一道有关hook的题,第一次做所以理解还比较浅,通过这道题先渐渐了解一下hook。
查壳无壳,直接拖入IDA
首先判断输入,如果长度是19就进入sub_401220函数,跟进
看到一堆系统函数,立刻懵了。然后就自己百度大致了解一下函数即参数猜测就可以
1.GetCurrentProcessId():获取当前进程的标示符,返回值是标示符
2.OpenProcess():用来打开一个已存在的进程对象,并返回进程的句柄
3.LoadLibraryA():将指定的模块加载到调用进程的地址空间中。
4.GetProcAddress():从指定的动态链接库 (DLL) 检索导出函数 (也称为过程) 或变量。
首先获取当前的进程标识符赋值给v2并且打开运行这个进程,把进程句柄返回给hProcess。跟进LibFileName是所以把kernel32模块调用在进程中。
kernel32.dll是Windows 9x/Me中非常重要的32位动态链接库文件,属于内核级文件。它控制着系统的内存管理、数据的输入输出操作和中断处理,当Windows启动时,kernel32.dll就驻留在内存中特定的写保护区域,使别的程序无法占用这个内存区域。
然后跟进后面的ProcName,发现是WriteFile,所以是从kernel32动态链接库引入WriteFile函数,并把地址给了lpAddress。(这个函数在后面有用到。)
关键是这段代码:
0xE9是jmp函数的机器码(很多人从这里凭借经验就知道是hook)。而dword_40C9BD的计算方式跟jmp偏移地址的计算方式十分类似。即偏移地址=目标地址-当前地址-5(减5原因看下面红字)
EASYHOOK XCTF 4TH-WHCTF-2017 攻防世界 通过此题理解hook钩子_hincon的博客-优快云博客_ctf hook几种跳转指令和对应的机器码:
0xE8 CALL后面的四个字节是地址
0xE9 JMP后面的四个字节是偏移
0xEB JMP后面的二个字节是偏移
0xFF15 CALL后面的四个字节是存放地址的地址
0xFF25 JMP后面的四个字节是存放地址的地址
0x68 PUSH后面的四个字节入栈
0x6AP USH后面的一个字节入栈
同时byte_40C9BC,dword_40C9BD内存地址还是连续的,如下这会不会就相当于有一个jmp操作,跳转到sub_401080处,是一个hook指令呢。然后跟进return sub_4010D0()
1.VirtualProtectEx():更改指定进程的虚拟地址空间中已提交的页面区域的保护
2.WriteProcessMemory():此函数能写入某一进程的内存区域 WriteProcessMemory(由OpenProcess返回的进程句柄,要写的内存首地址,指向要写的数据的指针。
WriteProcessMemory():则向lpAddress中写入jmp那个hook指令操作,让原本的地址WriteFile变为jmp sub_401080.
所以很明显知道主函数中CreateFileA->(lpAddress里存的指令)WriteFile->sub_401240,但是在经过sub_401220()的处理以后,变成了CreateFileA->(lpAddress里存的指令)sub_401080->sub_401240。所以执行的加密函数为sub_401080,跟进查看
这就是主函数输出“Right!flag is your input”成立的条件。跟进sub_401000
解密代码:
key=[0x61, 0x6A, 0x79, 0x67, 0x6B, 0x46, 0x6D, 0x2E, 0x7F, 0x5F, 0x7E, 0x2D, 0x53, 0x56, 0x7B, 0x38, 0x6D, 0x4C, 0x6E]
flag=list("-------------------")
for i in range(len(key)):
if i==18:
flag[i]=chr(key[i]^0x13)
else:
v3=key[i]^i
if i%2!=0:
flag[i]=chr(v3+i)
else:
flag[i+2]=chr(v3)
print(''.join(flag))