IDA入门笔记
题目来源:
南邮CTF :: RE :: Hello,RE(应该是)
XDUCTF :: ??? :: ????????(不知道不知道不知道)
总而言之我会在百度网盘再上传一份: >>百度网盘, 提取码 3dcv <<
0> 总结
1> 查看.exe是32位还是64位的: notepad++打开,Ctrl-F找"PE", 若位PE……L则为32位,若为PE……d则为64位。
2> IDApro常用快捷键:
1> F5 : 嘿嘿嘿
2> R : 将看不懂的数据转化为可能看懂的数据
3> Y : 修改变量/函数类型
4> N : 修改变量/函数名
5> X : 查看变量/函数被引用情况
6> U : 将此处还原到初始状态
7> D : 在汇编语言界面,改变数据类型
8> TAB : 切换显示形式 ……(待续)
9> F2 : 设置断点
10> G : 动态调试界面,跳转到目标地址
3> 常规操作:
1> 修参数:名称 && 类型
2> 动态调试:断点 && 栈
1> 准备:
操作系统:windows //建议win7或以上
IDA //可以去"吾爱破解"论坛自行下载。
C语言编译器 或者 IDA的插件 "Lazy IDA" //由于当时没时间配置LazyIDA,所以一些步骤只好自己写。
notepad++ //官网传送门
2> 0.exe
1> 用Notepad++打开0.exe,发现"PE @#$%^&*( L ", 说明这个可执行文件是32位的。 //若为"PE!@#$%^&*() d" ,则说明是64位的。
2> 拖到idaq(32位)里,一路ok
3> 选中_main函数,F5
4> 选中v5等的那些数字,按R,就可以把她们变为可以阅读的文字。
5> 显然这就是每一小节倒置后的flag,可以手动敲出来。
不过,由于是用strcmp函数比较输入数据和答案是否匹配,我们还可以尝试动态调试。
6> 在第二步的那个界面里(IDA VIEW-A),选中_strcmp, 摁X看看哪里调用了这个家伙。
7> 设置断点(F2), 效果如图:
8> 在上边的小条条里选中"Local Win32 debugger",按绿色的运行按钮开始动态调试。
9> 随便输一串啥东西,回车确定。发现不动弹了,这是正常的。
10> 在右下角的stack view里我们可以发现两个神奇的地址。
11> 复制,选中它左边的窗口(Hex View-1),按G跳转到地址,贴进去,OK.
12> 找到了之前丢进去的东西。
13> 那么第二个地址就应该是flag了,如法炮制,GET~
3> 1.exe
1> 先运行一下。
发现输入之后闪了一下就推出了,恼火。
2> 不行,恼火,Win+R开cmd,重新运行一次。
发现了可以用来定位的字符。
3> notepad打开,是32位的。
4> 拖进IDA(32位),发现没有main函数。
//我起初以为哪个start函数就是主函数,然而盯着屏幕看了几分钟之后我发现我错了。 看不懂
5> 这时,最开始我们见到的那些文字就有用了。在view--open subviews-strings 里搜索。
6> 随便点一个好了(双击)
7> 摁X看引用,OK.
8> F5,发现sub_401020()就是main
9> 选中函数名,摁N重命名,改为"main”
10> 我们可以看到主函数干了很多骚操作,乱七八糟的不想看下去。
11> 不过,粗略一读,可以发现sub_401450就是printf,摁N重命名。
12> 在那个带有"flag字样的if语句里",我们可以发现,显示对一个名字叫Str的东西做了sub_4013C0,然后把它和flag格式的头和尾巴作比较。
看看sub_401340,就是exit.
于是我们大胆猜测,sub_4013C0就是scanf,而这个if语句就是在判断输入内容是否符合flag的格式。
从初中到大学的所有数学证明题,不都是"没原因,但就是知道该这样做" 吗?(啧啧啧)
13> 摁N改名,顿时清晰(了一些)。
14> 验证的语句是"strcmp",所以改名。
15> 小结
先让用户输入flag,判断是否符合格式,若不符合则退出程序。
然后把flag去掉格式,复制到DST //DST即flag{内的内容},暂且重命名为"flag_body"
再对DST进行sub_4011F0操作(有些复杂,暂不处理)
之后把DST和v4进行一些奇怪的操作
最后判断v4是否符合a23g……那个字符串
如果是,就是。否则退出。
16> 综上所述,再次大胆猜想,
sub_4011F0和sub_401270是加密算法,
而a23……是加密后的flag,
于是,接下来的任务就是看懂加密算法,并写出解密算法。
17> sub_4011F0
可以看到,v2本应是int,却显示为char。(虽说根本没啥卵用就是了)
而根本不需要返回值,所以我们需要无视和result有关的语句。(有插件,之后有机会补上)
1> 函数,判断了一下函数是否满足一个和32有关的条件,然后再把传入的flag和另一个数组亦或。
可以发现,flag的长度为32。
2> 双击查看dword4040,很显然这是一个每个元素大小为4B的数组。
3> 右键,array,将这个家伙转化为数组,32个元素。
4> 显然,这就是与flag异或的数组。
XOR的逆运算还是XOR,所以只需要把这玩意转化一下即可。 //转化方法在后面
18> sub_401270
1> 改变量名(len, i, input, output)
2> 改变量类型(output是个char*)
3> 可以发现,加密原理是根据"a1"这个东西将输入的顺序调换,从而转化为密文。所以,a1即所谓的"key"
4> 返回main,找到所谓"a1",,双击。
5> 转化为int数组,先如下图操作,然后右键-array,32个元素。
1> 按d转化数据类型为dd(即整型)
2> 右键-array -32个元素
//若误操作,你会发现没有撤销功能,然而可以按U将该单元重置。
6> 先在我们需要转化的两组key就都在这里了。
7> 然后就可以进行解密操作了。
19> sub_401270的解密算法
注释:
0> 伪代码
1> key2即映射规则,即dword_4040C0
2> output和input分别是这条函数的输出数据和输入数据。
加密算法:
for(int i=; i<; i++) output[key2[i]] = input[i];
解密算法:
for(int i=; i<; i++) output[i] = input[key2[i]]
20> sub_4011F0的解密算法
注释:
0> 伪代码
1> key1即dword_404040
2> " ^ "是异或(XOR),逆运算还是异或。
加密算法:
for(int i=; i<len; i++) flag[i] ^= key1[i];
解密算法:(同上)
for(int i=; i<len; i++) flag[i] ^= key1[i];
21> 如何将形如"53h"的十六进制数丢进C++ lazy IDA 或者 自己写代码。
注释:
1> C++只能识别形如"0x53"的十六进制数而不能识别形如"53h"的十六进制数
2> 写一段处理字符串的函数即可
3> 因为懒得写,所以手工处理了一部分。只需把"dd"去掉;把换行符换为" ,"即可。
3.5> 因为懒得整合,所以把处理key的函数和主函数分开写了。需要手工复制粘贴一下,不过好在代码行数少,DEBUG比较方便。
4> 代码如下,在程序所在目录下新建in.txt,把东西丢进去,略作处理,保存,运行程序即可。
手工处理之后的key1:
53h, 45h, 5Ch, 1Eh, 50h, 13h, 2Fh, 78h, , 53h, 58h, 4Ah, 43h, , 41h, 2Ah, , 40h, 67h, 2Fh, 0Ch, 4Ah, 12h, 2Eh, 41h, 6Ch, , 54h, 40h, 12h, 5Bh, 4Fh
手工处理之后的key2:
, 0Fh, 0Bh, 1Eh, 0Eh, 14h, 1Fh, , 17h, , 19h, 1Ch, 12h, 10h, , , 11h, , 15h, , 0Ah, 1Dh, 0Ch, 16h, 18h, 0Dh, 1Bh, , , , 13h, 1Ah
代码:
#include<cstdio>
#include<cstdlib>
int main() {
freopen("out2.txt", "w", stdout);
char ans[] = "23gjf13au98hk3a1090zp8qjs41h39jp";
char flag[];
int key2[] = {0x4, 0x0F, 0x0B, 0x1E, 0x0E, 0x14, \
0x1F, 0x9, 0x17, 0x2, 0x19, 0x1C, 0x12, 0x10, 0x0, 0x8, \
0x11, 0x1, 0x15, 0x3, 0x0A, 0x1D, 0x0C, 0x16, 0x18, 0x0D, \
0x1B, 0x5, 0x7, 0x6, 0x13, 0x1A};
int key1[] = {0x53, 0x45, 0x5C, 0x1E, 0x50, 0x13, \
0x2F, 0x78, 0x4, 0x53, 0x58, 0x4A, 0x43, 0x1, 0x41, 0x2A, \
0x8, 0x40, 0x67, 0x2F, 0x0C, 0x4A, 0x12, 0x2E, 0x41, 0x6C, \
0x5, 0x54, 0x40, 0x12, 0x5B, 0x4F};
for(int i=; i<; i++) {
flag[i] = ans[key2[i]];
}
for(int i=; i<; i++) {
flag[i] ^= key1[i];
}
printf("%s\n", flag);
fclose(stdout);
system("out2.txt");
return ;
}
22> 整合,运算:
注释:
1> flag:原程序的输入数据,同时也是本程序的输出数据
2> ans:本程序的输入数据,同时也是原程序的输出数据
3> 运行即可,自动弹出盛放有flag的txt
代码:
#include<cstdio>
#include<cstdlib>
using namespace std;
int main() {
freopen("out2.txt", "w", stdout);
char ans[] = "23gjf13au98hk3a1090zp8qjs41h39jp";
char flag[];
int key2[] = {0x4, 0x0F, 0x0B, 0x1E, 0x0E, 0x14, \
0x1F, 0x9, 0x17, 0x2, 0x19, 0x1C, 0x12, 0x10, 0x0, 0x8, \
0x11, 0x1, 0x15, 0x3, 0x0A, 0x1D, 0x0C, 0x16, 0x18, 0x0D, \
0x1B, 0x5, 0x7, 0x6, 0x13, 0x1A};
int key1[] = {0x53, 0x45, 0x5C, 0x1E, 0x50, 0x13, \
0x2F, 0x78, 0x4, 0x53, 0x58, 0x4A, 0x43, 0x1, 0x41, 0x2A, \
0x8, 0x40, 0x67, 0x2F, 0x0C, 0x4A, 0x12, 0x2E, 0x41, 0x6C, \
0x5, 0x54, 0x40, 0x12, 0x5B, 0x4F};
for(int i=; i<; i++) {
flag[i] = ans[key2[i]];
}
for(int i=; i<; i++) {
flag[i] ^= key1[i];
}
flag[] = '\0';
printf("%s\n", flag);
fclose(stdout);
system("out2.txt");
return ;
}
运行结果:
即:
flag{5t4t1c_An4lys1s_1s_E4sy_2_me!!!~}
IDA入门笔记的更多相关文章
- 每天成长一点---WEB前端学习入门笔记
WEB前端学习入门笔记 从今天开始,本人就要学习WEB前端了. 经过老师的建议,说到他每天都会记录下来新的知识点,每天都是在围绕着这些问题来度过,很有必要每天抽出半个小时来写一个知识总结,及时对一天工 ...
- ES6入门笔记
ES6入门笔记 02 Let&Const.md 增加了块级作用域. 常量 避免了变量提升 03 变量的解构赋值.md var [a, b, c] = [1, 2, 3]; var [[a,d] ...
- [Java入门笔记] 面向对象编程基础(二):方法详解
什么是方法? 简介 在上一篇的blog中,我们知道了方法是类中的一个组成部分,是类或对象的行为特征的抽象. 无论是从语法和功能上来看,方法都有点类似与函数.但是,方法与传统的函数还是有着不同之处: 在 ...
- React.js入门笔记
# React.js入门笔记 核心提示 这是本人学习react.js的第一篇入门笔记,估计也会是该系列涵盖内容最多的笔记,主要内容来自英文官方文档的快速上手部分和阮一峰博客教程.当然,还有我自己尝试的 ...
- redis入门笔记(2)
redis入门笔记(2) 上篇文章介绍了redis的基本情况和支持的数据类型,本篇文章将介绍redis持久化.主从复制.简单的事务支持及发布订阅功能. 持久化 •redis是一个支持持久化的内存数据库 ...
- redis入门笔记(1)
redis入门笔记(1) 1. Redis 简介 •Redis是一款开源的.高性能的键-值存储(key-value store).它常被称作是一款数据结构服务器(data structure serv ...
- OpenGLES入门笔记四
原文参考地址:http://www.cnblogs.com/zilongshanren/archive/2011/08/08/2131019.html 一.编译Vertex Shaders和Fragm ...
- OpenGLES入门笔记三
在入门笔记一中比较详细的介绍了顶点着色器和片面着色器. 在入门笔记二中讲解了简单的创建OpenGL场景流程的实现,但是如果在场景中渲染任何一种几何图形,还是需要入门笔记一中的知识:Vertex Sha ...
- unity入门笔记
我于2010年4月1日硕士毕业加入完美时空, 至今5年整.刚刚从一家公司的微端(就是端游技术+页游思想, 具体点就是c++开发, directX渲染, 资源采取所需才会下载)项目的前端主程职位离职, ...
随机推荐
- OpenStack Grizzly详细安装指导
一.环境介绍: 控制节点 eth0 (10.10.10.51), eth1 (192.168.100.51) 网络节点 eth0 (10.10.10.52), eth1 (10.20.20.52), ...
- 20145203JAVA课程总结
20145203盖泽双 <Java程序设计>课程总结 课程总结 (按顺序)每周读书笔记链接汇总 调查问卷:http://www.cnblogs.com/GZSdeboke/p/524832 ...
- CentOS部署Kubernetes1.13集群-1(使用kubeadm安装K8S)
参考:https://www.kubernetes.org.cn/4956.html 1.准备 说明:准备工作需要在集群所有的主机上执行 1.1系统配置 在安装之前,需要先做如下准备.三台CentOS ...
- 代码中会话同步(同步redis)导致的异常问题
背景: 第一天拷贝了一份tomcat(配置了redis会话同步),部署了erp-rocketmq应用(用作给顾客发送消息). 第二天早晨,整个erp系统出现异常情况: 1> ...
- jenkins -Djava.awt.headless=true Linux下java.awt.HeadlessException的解决办法
修改 linux apache-tomcat-7.0.56/bin \catalina.sh文件 在所有类似以下代码大约有七八处具体自己去看: "$_RUNJAVA" $J ...
- smtp outlook邮件发送非授权码模式
1.起因:send fail SMTP AUTH extension not supported by server. 使用端口25 和587均失效出现此问题 首先前往outlook修改设置pop和I ...
- linux 学习第二十天(mariadb配置)
一.mariadb yum install mariadb mariadb-server systemctl restart mariadb systemctl enable mariadb mysq ...
- laravel5.5源码笔记(八、Eloquent ORM)
上一篇写到Eloquent ORM的基类Builder类,这次就来看一下这些方便的ORM方法是如何转换成sql语句运行的. 首先还是进入\vendor\laravel\framework\src\Il ...
- PHP通过_call实现多继承
原文地址:http://small.aiweimeng.top/index.php/archives/53.html 上一篇讲到php可以通过接口是实现代码的复用. 那么这篇文章简单介绍下使用_cal ...
- WPF 学习笔记-在WPF下创建托盘图标
原文:WPF 学习笔记-在WPF下创建托盘图标 首先需要在项目中引用System.Windows.Forms,System.Drawing; using System; using System.Co ...