【CTF REVERSE】ctf02-查找字符串
1、前言
公司大拿给写的一个CTF逆向程序,提升我们组内人员的水平。
基于对话框MFC框架开发,使用EDIT控制特性隐藏Flag,可借助spy4win之类窗体工具找出Flag。
程序加UPX壳,已对壳信息混淆处理,PEiD无法识别出壳信息。
DLL 依赖情况如图所示。
2、思路
程序用IDA查看的时候,因为有壳混淆后是没法跟下去的。这道题比较简单,破解还是常规思路。。。
- 1)手动脱UPX壳
- 2)IDA查找字符串,获取信息
- 3)跟踪调用的函数
3、过程
1、脱壳
UPX是一款常用的压缩壳,单步跟踪法或者是ESP定律都能很快的脱掉它。
单步跟踪到如下反汇编指令处:
00406A10 pushad
00406A11 mov esi,ctf02.00406000
00406A16 lea edi,dword ptr ds:[esi-0x5000]
00406A1C push edi
00406A1D or ebp,-0x1
00406A20 jmp short ctf02.00406A32
F8单步向下运行,遇到向上的跳转就F4到下一条指令去,不让自己迷失在各种解密操作指令中。
00406A32 mov ebx,dword ptr ds:[esi]
00406A34 sub esi,-0x4
00406A37 adc ebx,ebx
00406A39 jb short ctf02.00406A28 ; 向上跳转,跳转实现向上运行
00406A3B mov eax,0x1 ; F4运行到此处,遇到红色跳转就下一条
00406A40 add ebx,ebx
00406A42 jnz short ctf02.00406A4B
00406A44 mov ebx,dword ptr ds:[esi]
00406A46 sub esi,-0x4
00406A49 adc ebx,ebx
00406A4B adc eax,eax
00406A4D add ebx,ebx
00406A4F jnb short ctf02.00406A40
00406A51 jnz short ctf02.00406A5C
00406A53 mov ebx,dword ptr ds:[esi]
00406A55 sub esi,-0x4
00406A58 adc ebx,ebx
00406A5A jnb short ctf02.00406A40
00406A5C xor ecx,ecx
00406A5E sub eax,0x3
00406A61 jb short ctf02.00406A70
00406A63 shl eax,0x8
00406A66 mov al,byte ptr ds:[esi]
00406A68 inc esi ; ctf02.0040600B
00406A69 xor eax,-0x1
00406A6C je short ctf02.00406AE2
00406A6E mov ebp,eax
00406A70 add ebx,ebx
接下来会遇见两个向上的跳转,一个小跳转,一个大跳转。
我们在NOP指令的下一行代码F4运行到那一条,接下来的操作就比较重复化,遇到跳转就F4到下一条。
然后遇到popad指令的时候说明我们距离OEP就不远了!
00406ABD mov al,byte ptr ds:[edx]
00406ABF inc edx ;
00406AC0 mov byte ptr ds:[edi],al
00406AC2 inc edi ;
00406AC3 dec ecx
00406AC4 jnz short ctf02.00406ABD ; 小跳转
00406AC6 jmp ctf02.00406A2E ; 大跳转
00406ACB nop
00406ACC mov eax,dword ptr ds:[edx] ; F4运行到此处
00406ACE add edx,0x4
00406AD1 mov dword ptr ds:[edi],eax
00406AD3 add edi,0x4
00406AD6 sub ecx,0x4
00406AD9 ja short ctf02.00406ACC ; 又是一个跳转的地方
00406ADB add edi,ecx ; F4运行到此处
00406ADD jmp ctf02.00406A2E ; 大跳转,F4运行到下一条语句
00406AE2 pop esi ;
00406AE3 mov edi,esi ; F4运行到此处
00406AE5 mov ecx,0x3B
00406AEA mov al,byte ptr ds:[edi]
00406AEC inc edi ;
00406AED sub al,0xE8
00406AEF cmp al,0x1
00406AF1 ja short ctf02.00406AEA ; 小跳转
00406AF3 cmp byte ptr ds:[edi],0x1 ; F4运行到此处
00406AF6 jnz short ctf02.00406AEA
00406AF8 mov eax,dword ptr ds:[edi] ; F4运行到此处
00406AFA mov bl,byte ptr ds:[edi+0x4]
00406AFD shr ax,0x8
00406B01 rol eax,0x10
00406B04 xchg ah,al
00406B06 sub eax,edi ;
00406B08 sub bl,0xE8
00406B0B add eax,esi ;
00406B0D mov dword ptr ds:[edi],eax
00406B0F add edi,0x5
00406B12 mov al,bl
00406B14 loopd short ctf02.00406AEF ; 循环操作
00406B16 lea edi,dword ptr ds:[esi+0x4000] ; F4运行到此处
00406B1C mov eax,dword ptr ds:[edi]
00406B1E or eax,eax
00406B20 je short ctf02.00406B67
00406B22 mov ebx,dword ptr ds:[edi+0x4]
00406B25>lea eax,dword ptr ds:[eax+esi+0x68BC]
00406B2C add ebx,esi ;
00406B2E push eax
00406B2F add edi,0x8
00406B32 call dword ptr ds:[esi+0x6920] ;
00406B38 xchg eax,ebp ;
00406B39 mov al,byte ptr ds:[edi]
00406B3B inc edi ;
00406B3C or al,al
00406B3E je short ctf02.00406B1C
00406B40 mov ecx,edi ;
00406B42 jns short ctf02.00406B4B
00406B44 movzx eax,word ptr ds:[edi]
00406B47 inc edi ;
00406B48 push eax
00406B49 inc edi ;
00406B4A db B9
00406B4B push edi ;
00406B4C dec eax
00406B4D repne scas byte ptr es:[edi]
00406B4F push ebp ;
00406B50 call dword ptr ds:[esi+0x6924] ;
00406B56 or eax,eax
00406B58 je short ctf02.00406B61
00406B5A mov dword ptr ds:[ebx],eax
00406B5C add ebx,0x4
00406B5F jmp short ctf02.00406B39 ; 无条件跳转
00406B61 call dword ptr ds:[esi+0x6934] ;
00406B67 mov ebp,dword ptr ds:[esi+0x6928] ; F4运行到此处
00406B6D lea edi,dword ptr ds:[esi-0x1000]
00406B73 mov ebx,0x1000
00406B78 push eax
00406B79 push esp
00406B7A push 0x4
00406B7C push ebx
00406B7D push edi ;
00406B7E call ebp ;
00406B80 lea eax,dword ptr ds:[edi+0x207]
00406B86 and byte ptr ds:[eax],0x7F
00406B89 and byte ptr ds:[eax+0x28],0x7F
00406B8D pop eax
00406B8E push eax
00406B8F push esp
00406B90 push eax
00406B91 push ebx
00406B92 push edi ;
00406B93 call ebp ;
00406B95 pop eax
00406B96 popad ; 到这里的时候说明快到OEP了
00406B97 lea eax,dword ptr ss:[esp-0x80]
00406B9B push 0x0
00406B9D cmp esp,eax
00406B9F jnz short ctf02.00406B9B
00406BA1 sub esp,-0x80
00406BA4 jmp ctf02.00401750 ; 跳转到OEP
到了00406BA4 这里的时候,我用OD插件-Ollydump脱壳。
2、IDA查看
脱了壳后的程序,用IDA看就没有障碍了。
IDA打开后-View - Open Subviews - Srings
然后X键,查看哪个函数在引用它,F5查看C源码就确认出Flag了。
signed int __thiscall sub_4012B0(CDialog *this)
{
CDialog *v1; // esi@1
HMENU v2; // eax@1
struct CMenu *v3; // edi@1
LPCSTR lpNewItem; // [sp+8h] [bp-10h]@2
int v6; // [sp+14h] [bp-4h]@2
v1 = this;
CDialog::OnInitDialog(this);
v2 = GetSystemMenu(*((HWND *)v1 + 8), 0);
v3 = CMenu::FromHandle(v2);
if ( v3 )
{
CString::CString(&lpNewItem);
v6 = 0;
CString::LoadStringA((CString *)&lpNewItem, 0x65u);
if ( *((_DWORD *)lpNewItem - 2) )
{
AppendMenuA(*((HMENU *)v3 + 1), 0x800u, 0, 0);
AppendMenuA(*((HMENU *)v3 + 1), 0, 0x10u, lpNewItem);
}
v6 = -1;
CString::~CString((CString *)&lpNewItem);
}
SendMessageA(*((HWND *)v1 + 8), 0x80u, 1u, *((_DWORD *)v1 + 40));
SendMessageA(*((HWND *)v1 + 8), 0x80u, 0, *((_DWORD *)v1 + 40)); //发送消息到窗口
CWnd::SetWindowTextA((CDialog *)((char *)v1 + 96), "6C9F69EF-C170-4e43-A007-9AA3526823DB"); //设置文本
SendMessageA(*((HWND *)v1 + 32), 0xCCu, 0x2Eu, 0);
return 1;
}
4、附件下载地址
5、参考
手脱UPX壳的几种方法
http://blog.csdn.net/xiaoyuai1234/article/details/51463501
【CTF REVERSE】ctf02-查找字符串的更多相关文章
- 在文件夹中 的指定类型文件中 查找字符串(CodeBlocks+GCC编译,控制台程序,仅能在Windows上运行)
说明: 程序使用 io.h 中的 _findfirst 和 _findnext 函数遍历文件夹,故而程序只能在 Windows 下使用. 程序遍历当前文件夹,对其中的文件夹执行递归遍历.同时检查遍历到 ...
- php查找字符串首次出现的位置 判断字符串是否在另一个字符串中
strpos - 查找字符串首次出现的位置 说明 int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] ) 返回 nee ...
- 查找字符串的 KMP 算法
查找字符串是我们平常编程过程中经常遇到的,现在介绍一种查找字符串算法,增加程序的执行速度. 通常我们是这么写的: /* content: search a string in a othor stri ...
- 回朔法/KMP算法-查找字符串
回朔法:在字符串查找的时候最容易想到的是暴力查找,也就是回朔法.其思路是将要寻找的串的每个字符取出,然后按顺序在源串中查找,如果找到则返回true,否则源串索引向后移动一位,再重复查找,直到找到返回t ...
- Lua查找字符串注意
问题: 使用Lua写Wireshark插件时,经常匹配字符串.今天使用string.find()函数查找字符串”max-age”,没有找到. 分析: local index = string.find ...
- Javascript 查找字符串中出现最多的字符和出现的次数
<script type="text/javascript"> //查找字符串中出现最多的字符和出现的次数 var str = 'Thatwheneying its o ...
- 查找字符串(C++实现)
查找字符串(C++实现),不使用库函数: // SubString.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include < ...
- php查找字符串是否存在
strstr //搜索字符串在另一字符串中的首次出现(对大小写敏感) //该函数返回字符串的其余部分(从匹配点).如未找到则返回 false stristr //查找字符串在另一字符串中第一次出现的位 ...
- linux上查找文件存放地点和文件中查找字符串方法
一.查找文件存放地点 1.locate 语法:locate <filename> locate命令实际是"find -name"的另一种写法,但是查找方式跟find不同 ...
随机推荐
- MT【46】不动点,稳定点几何直观
评:不动点概念在数列的一类题中也是非常有用的.
- 说说Java 位运算
前言 我们都知道,在计算机世界里,再复杂,再美的程序,到最后都会变成0与1.也就是我们常说的:二进制.二进制相信大家都很熟悉.与现实世界不同的是,在现实世界里,我们通常都是用十进制来表示的,也就是遇十 ...
- 稍稍乱入的CNN,本文依然是学习周莫烦视频的笔记。
稍稍乱入的CNN,本文依然是学习周莫烦视频的笔记. 还有 google 在 udacity 上的 CNN 教程. CNN(Convolutional Neural Networks) 卷积神经网络简单 ...
- 自学Linux Shell7.3-linux共享文件
点击返回 自学Linux命令行与Shell脚本之路 7.3-linux共享文件 在linux系统中共享文件的方法是通过创建组. 1. linux为每个文件和目录存储了3个额外的信息位: SUID设置用 ...
- volatile的实现原理与应用
Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现和CPU的指令. vola ...
- A1080. Graduate Admission
It is said that in 2013, there were about 100 graduate schools ready to proceed over 40,000 applicat ...
- [luoguU42591][小T的面试题]
luoguU42591 题意: n个不超过n的正整数中,其中有一个数出现了两次,其余的数都只出现了一次, 求这个出现两次的数. 思路: 这个题的亮点在于内存限制1MB.明显不能再用数组储存了,肯定是用 ...
- 关于vue里页面的缓存
keep-alive是vue内置的一个组件,可以使被它包含的组件处于保留状态,或避免被重新渲染. 用法: 运行结果描述: input输入框内,路由切换输入框内部的内容不会发生改变. 在keep-ali ...
- typescript函数(笔记非干货)
函数类型 Function Type 为函数定义类型 Define types for functions 我们可以给每个参数添加类型之后再为函数本身添加返回值类型. TypeScript能够根据返回 ...
- 和我一起使用webpack构建react项目
第一步:初始化项目并创建package.json文件 第二步:创建webpack.config.js文件,并写入配置. 第三步:安装webpack以及创建es6语法环境,要将html作为模板文件解析的 ...