内网门户网站建设,代运营是什么意思,西安市在建工程项目,哪里有做企业网站的参考文章#xff1a;
re学习笔记#xff08;27#xff09;攻防世界-re-csaw2013reversing2_Forgo7ten的博客-CSDN博客攻防世界逆向入门题之csaw2013reversing2_沐一 林的博客-CSDN博客
三种做法
1、ida静态分析修改指令
main函数反编译的代码 由于运行之后的是乱码
re学习笔记27攻防世界-re-csaw2013reversing2_Forgo7ten的博客-CSDN博客攻防世界逆向入门题之csaw2013reversing2_沐一 · 林的博客-CSDN博客
三种做法
1、ida静态分析修改指令
main函数反编译的代码 由于运行之后的是乱码所以可以猜测生成flag的函数没有执行所以需要跳到生成flag的函数执行但是前面的中断函数不能执行需要nop掉并且后面退出程序的函数不能执行需要跳到弹框函数继续执行。修改的路径和文件名不要有中文我用ida修改的时候踩了坑大家可以试一试 一.ida修改代码的方法 1、鼠标停留在要修改的汇编代码上然后点击Edit Patch program Assemble中文编辑 修补程序 汇编 2、修改完成后Edit Patch program Apply pathes to input file OK中文编辑 修补程序 修补程序应用到输入文件 确定 二.IDA图形视图讲解 图形视图将一个函数分解成许多基本块以生动显示该函数由一个块到另一个块的控制流程 基本块是一个不包含分支从头执行到尾的最大指令序列 基本块中的第一条指令通常是分支指令的目标而最后一条指令则往往是一条分支指令 IDA 使用不同的彩色箭头区分函数块之间各种类型的流 正常流也叫做普通流表示指令默认连续执行跳转流表示当前的指令跳转到或可能跳转到某个非连续性位置调用流表示当前指令会调用一个子例程 根据测试条件在条件跳转位置终止的基本块可能会生成两种流Yes 边的箭头是的执行分支默认为绿色No 边的箭头不不执行分支默认为红色 只有一个后继块的基本块会利用一个正常边默认为蓝色指向下一个即将执行的块 在图形模式下IDA 一次显示一个函数 使用滑轮鼠标的用户可以使用“CTRL鼠标滑轮”来调整图形的大小 修改之前的汇编代码 修改之后的汇编代码 修改完成之后直接运行文件得到flag 2、ollydbg动态调试nop大法
将文件导入ollydbg后直接右键 中文搜索引擎 智能搜索找到Flag 双击之后向上找到IsDebuggerPresent函数点击这句汇编下断点重新载入 F8两次发现一个跳转根据之前ida的分析这应该就是那个if语句的判断跳过的中间部分就是生成flag的函数所以我们把这个跳转nop掉 继续F8执行执行到int 3这是中断语句所以也nop掉 F8执行完生成flag的函数后后面有一个大跳转跳到退出程序的函数 所以我们把这个跳转也给nop掉继续F8执行完一个MessageBoxA弹框函数后发现程序此时处于Running状态弹出一个什么也没有的框其实这是另外一个弹框函数真正输出flag的弹框函数是后面那个在我们之前那个ida的修改之后的汇编图也可以发现确实是有一个没有被调用的弹框函数所以我们之前可以那个nop掉的跳转改为跳转到下面那个弹框函数但既然说了是nop大法就nop到底 点击中止之后发现又要执行一个跳转跳过了我们真正的弹框函数 将这个跳转nop掉接着F8就可以看到flag了 3、 分析代码写脚本
main函数代码
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{int v3; // ecxCHAR *lpMem; // [esp8h] [ebp-Ch]HANDLE hHeap; // [esp10h] [ebp-4h]hHeap HeapCreate(0x40000u, 0, 0);lpMem (CHAR *)HeapAlloc(hHeap, 8u, MaxCount 1);memcpy_s(lpMem, MaxCount, unk_409B10, MaxCount);if ( sub_40102A() || IsDebuggerPresent() ){__debugbreak();sub_401000(v3 4, lpMem);ExitProcess(0xFFFFFFFF);}MessageBoxA(0, lpMem 1, Flag, 2u);HeapFree(hHeap, 0, lpMem);HeapDestroy(hHeap);ExitProcess(0);
} 关键函数sub_401000的两个参数v3后面没有用到向上找lpMem的赋值语句memcpy_s将unk_409B10地址的值给了它双击查看 进入sub_401000函数内部代码
unsigned int __fastcall sub_401000(int a1, int a2)
{int v2; // esiunsigned int v3; // eaxunsigned int v4; // ecxunsigned int result; // eaxv2 dword_409B38;v3 a2 1 strlen((const char *)(a2 1)) 1;v4 0;result ((v3 - (a2 2)) 2) 1;if ( result ){do*(_DWORD *)(a2 4 * v4) ^ v2;while ( v4 result );}return result;
} a2也就是lpMem发现后面的异或语句有v2向上找v2的赋值语句找到v2 dword_409B38双击dword_409B38找到内容 这里是四个字节显示的又由于小端存储所以顺序是颠倒的我们可以将其转换成一个字节查看 wp:
x[0xbb,0xaa,0xcc,0xdd]
y[0xBB,0xCC,0xA0,0xBC,0xDC,0xD1,0xBE,0xB8,0xCD,0xCF,0xBE,0xAE,0xD2,0xC4,0xAB,0x82,0xD2,0xD9,0x93,0xB3,0xD4,0xDE,0x93,0xA9,0xD3,0xCB,0xB8,0x82,0xD3,0xCB,0xBE,0xB9,0x9A,0xD7,0xCC,0xDD]
i0
z[]
while ilen(y):tchr(y[i]^x[i%4])z.append(t)i1
print(z)
print(.join(z))
[\x00, f, l, a, g, {, r, e, v, e, r, s, i, n, g, _, i, s, _, n, o, t, _, t, h, a, t, _, h, a, r, d, !, }, \x00, \x00] flag{reversing_is_not_that_hard!}
这里就可以知道为什么调用第一个弹窗会输出空白因为第一个弹窗函数是直接从第一个字符输出的但是第一个字符解码后为\0,直接截断所以会输出空白第二个弹窗是从lpMem1开始输出的