前言:
坛友们,年轻就是资本,和我一起逆天改命吧,我的学习过程全部记录及学习资源:https://www.52pojie.cn/thread-1791705-1-1.html
立帖为证!--------记录学习的点点滴滴
0x1 Windows初级题
1.使用IDA查看main函数程序流程图,可以看到成功的字符串提示在这里
2.再去看如何进入这个分支,提示输入密码:下面左边是错误分支,得让他往右边走
3.先看第一个关键跳:比较了一个36,猜测是判断输入字符串的长度
.text:00402284 83 7D E8 24 cmp [ebp+var_18], 36
.text:00402288 8B 5D EC mov ebx, [ebp+var_14]
.text:0040228B 8B 7D D8 mov edi, [ebp+var_28]
.text:0040228E 74 22 jz short loc_4022B2
4.去OD里面验证,先用study PE工具固定一下基址,防止干扰我们对比,去00402284打上断点,输入一个长度为36的字符串,然后跳过失败的地方
00402284 |. 837D E8 24 cmp [local.6],0x24
00402288 |. 8B5D EC mov ebx,[local.5]
0040228B |. 8B7D D8 mov edi,[local.10]
0040228E |. 74 22 je short 1.004022B2
00402290 |. BA F8A94200 mov edx,1.0042A9F8 ; ASCII "Error, please try again"
00402295 |. E8 36050000 call 1.004027D0
0040229A |. 50 push eax ; 1.0042E088
0040229B |. E8 E0070000 call 1.00402A80
004022A0 |. 68 10AA4200 push 1.0042AA10 ; ASCII 50,"ause"
004022A5 |. E8 44840000 call 1.0040A6EE
004022AA |. 83C4 08 add esp,0x8
004022AD |. E9 D8000000 jmp 1.0040238A
004022B2 |> 83EC 18 sub esp,0x18
5.再回去看ida流程图,发现右边分支是到失败的地方,那么我们得让他走左边的流程:
6.再去OD单步走,注意刚刚ida里面看到的关键跳的地方,就发现右边寄存器窗口ecx中疑似出现了flag,然后单步走就能分析出这是一个循环,拿我输入的字符串和ecx逐个比较,相等就成功。
004022E8 |. 837D D0 24 cmp [local.12],0x24
004022EC |. 75 48 jnz short 1.00402336
004022EE |. BE 20000000 mov esi,0x20
004022F3 |> 8B02 /mov eax,dword ptr ds:[edx] ; 从edx取值赋值给eax
004022F5 |. 3B01 |cmp eax,dword ptr ds:[ecx] ; 观察寄存器,这一步之后就把eax中的四个字符ascii码了
004022F7 |. 75 0F |jnz short 1.00402308
004022F9 |. 83C2 04 |add edx,0x4
004022FC |. 83C1 04 |add ecx,0x4
004022FF |. 83EE 04 |sub esi,0x4
00402302 |.^ 73 EF \jnb short 1.004022F3
00402304 |. 33C0 xor eax,eax
00402306 |. EB 25 jmp short 1.0040232D
00402308 |> 3A01 cmp al,byte ptr ds:[ecx] ; 然后比教我输入的第一个字符和ecx第一个字符是否相等
0040230A |. 75 1C jnz short 1.00402328
0040230C |. 8A42 01 mov al,byte ptr ds:[edx+0x1] ; 将我第二个字符给al
0040230F |. 3A41 01 cmp al,byte ptr ds:[ecx+0x1] ; 拿ecx第二个字符和我输入的第二个字符比较
00402312 |. 75 14 jnz short 1.00402328
00402314 |. 8A42 02 mov al,byte ptr ds:[edx+0x2] ; 同理
00402317 |. 3A41 02 cmp al,byte ptr ds:[ecx+0x2]
0040231A |. 75 0C jnz short 1.00402328
0040231C |. 8A42 03 mov al,byte ptr ds:[edx+0x3] ; 同理
0040231F |. 3A41 03 cmp al,byte ptr ds:[ecx+0x3]
00402322 |. 75 04 jnz short 1.00402328
00402324 |. 33C0 xor eax,eax
00402326 |. EB 05 jmp short 1.0040232D
00402328 |> 1BC0 sbb eax,eax
0040232A |. 83C8 01 or eax,0x1
0040232D |> BA 18AA4200 mov edx,1.0042AA18 ; ASCII 53,"uccess"
00402332 |. 85C0 test eax,eax
00402334 |. 74 05 je short 1.0040233B
00402336 |> BA 20AA4200 mov edx,1.0042AA20 ; ASCII 57,"rong,please try again."
7.现在知道正确的输入了,那么我就用正确的字符串试试,成功。
0x2 Android初级题一
1.运行一下apk,就是论坛的圈小猫游戏:
2.似乎难度有点大,还有点拼运气,用jadx打开找找提示,先看到下面的flag字符串,然后在看到调用这个函数的地方,再然后上面是一个playVideo函数。
3.然后继续往上翻,看标黄的地方,成功找到了文件路径,再看一下代码找到了加载它的类MyJavaScriptInterface。
public class MyJavaScriptInterface {
private Context mContext;
public MyJavaScriptInterface(Context context) {
this.mContext = context;
}
@JavascriptInterface
public void onSolverReturnValue(int i) {
if (i == -1) {
this.mContext.startActivity(new Intent(this.mContext, YSQDActivity.class));
}
}
}
4.可以看到主类启动的时候创建了MyJavaScriptInterface类对象,看到加载了一个文件:///android_asset/index.html
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_main);
copyAssets();
WebView webView = (WebView) findViewById(R.id.webView);
this.webView = webView;
webView.setInitialScale(100);
this.webView.getSettings().setJavaScriptEnabled(true);
this.webView.setWebViewClient(new WebViewClient());
this.webView.loadUrl("file:///android_asset/index.html");
this.webView.addJavascriptInterface(new MyJavaScriptInterface(this), "AndroidInterface");
}
5.然后暂时没有头绪了,n小时后回来再看看flag那一段代码,
public static String extractDataFromFile(String str) { //这里str通过前面分析知道就是那个mp4文件了
try {
RandomAccessFile randomAccessFile = new RandomAccessFile(str, "r");//创建一个读文件的类
long length = randomAccessFile.length();//计算一下长度
for (long max = Math.max(length - 30, 0L); max < length; max++) {//max似乎是从最大的,可能是读末尾的30个字符串
randomAccessFile.seek(max);
byte[] bArr = new byte[30];
randomAccessFile.read(bArr);//将末尾的30个字符串读到bArr
String str2 = new String(bArr, StandardCharsets.UTF_8);
int indexOf = str2.indexOf("flag{");
if (indexOf != -1) {
String str3 = str2.substring(indexOf).split("\\}")[0] + "}";
randomAccessFile.close();
return str3;
}
}
randomAccessFile.close();
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
6.将mp4修改为txt文件,记事本打开,都是乱码,让后换winhex16进制文本查看工具,在末尾发现了疑似flag,提交。
0x3 Android初级题二
1.运行一下apk,这是测试非酋和欧皇吗?90次就行了?这么简单?
2.我抽,等等,怎么不太对劲,时间间隔怎么越来越长?
3.jadx打开,我去找找千分之6在哪,再去Android killer中看smali代码,居然没找到,功力太浅。
4.静态不明显,中文字符串也搜不到,那就只能老老实实的抽了,但是要我等那么长时间是不可能的,丢进jeb,搜索提示道具不足的地方:
5.上面关键跳,Ctrl+B打上断点跑起来,经过多次测试,知道了p1就是我们剩余的道具,下面就是补充的时间间隔:
6.那么我要回去看smali代码,改生成道具时间吗?Androidkiller用不好,不折腾了,直接像od那样强制改变寄存器的值不就好了。
7.根据前面的尝试,知道了这里面第一个变量是剩余道具,第二个是已经抽奖的次数,第三个是生成道具还需等待的时间,既然90发保底必出,那我就改成如下图所示的值(假设已经祈愿80次,这次10个道具充足)。
8.一发入魂,得到flag,假装自己很欧。
0x4 总结
1.作为菜鸟的思路,反正就是先找字符串,搜字符串,找关键跳,改值。
2.看不懂的代码猜,猜测后去动态调试验证,是对的就继续,不对就找找其他出路。