我也只是花了一两天的时间大致地去了解了一下异常处理的机制,关于许多细节,自己也只能暂时忽略掉了。并且异常处理在逆向中的分析,相关资料少的可怜,自己的开发经验更是少的可怜。还是那句话,软件逆向的基础是软件正向开发。以后还是要系统学习一下C++(望向了那本678页的C++ Primer Plus 哭)。
先了解异常处理
异常是程序在执行期间产生的问题。C++ 异常是指在程序运行时发生的特殊情况,比如尝试除以零的操作。
异常提供了一种转移程序控制权的方式。C++ 异常处理涉及到三个关键字:try、catch、throw。
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
int main(void)
{
int b;
std::cin>>b;
try {
int a = 1;
if (!b)throw "Error!";//throw 什么类型 后面catch内写什么类型。可以是int double char 甚至类
std::cout << "success and Answer is ";
std::cout << a / b << std::endl;
}
catch(const char * msg) {//catch(...)处理一切类型的异常
std::cout << msg << std::endl;
std::cout << "" << std::endl;
}
}
/*
1
success and Answer is 1
0
Error!
*/
写好代码后,分别使用g++、MSVC编译后拖入IDA。Why?因为反汇编出来的代码大相径庭,所以感觉两种都得学会如何正确地去 patch 。
非常非常推荐阅读这一篇大佬的博客
例题
DASCTF X CBCTF 2022九月挑战赛 landing
这道题当时有做,一直都是得到一个wrong flag。之后才知道是异常处理机制。
无壳,GCC编译。
进来就看到一个花指令
直接E8->90
进入func1()后再进入func2()
也能知道抛出的是char*(a1是char *),我们要去寻找catch块(根据栈展开),我们找到了catch块
既然找到了catch块,根据之前大佬的博客,我们直接使用IDA插件 Keypatch(非常好用的插件),将call指令patchpatch成jmp指令。
懒,直接SHIFT+F2用IDApython得到地址。然后在call处直接patch
得到正确的函数。
EXP
这块代码的逻辑不难,需注意一下nothing在base64加密时偷偷加了一个1
上脚本
import base64
x='GUw\\D~UHG#kYG~\x7F'
y='BA#{QJT(\\A {BG~$BG~$BGz//'
x=x+y
flag1=''
for i in range(len(x)):
flag1+=chr((ord(x[i])^0x12)-1)
print(flag1)
flag1=flag1[:-2]
flag1+='=='
flag=base64.b64decode(flag1)
for i in range(28):
print(chr((int(flag[i])-1)^0x22),end='')
#itisbulijojodebuliduoooooooo
[长城杯 2022 政企组]rabbit_hole
无壳,MSVC编译(恼)
上来就是二十几个花指令(其实就两种),我就用IDAPython写脚本批量去除了。但是说实话,网上搜不到什么脚本。只好去查IDAPython文档自己写。
addrStart=0x4011E0
addrEnd=0x401A3B
num=0
#print((get_bytes(addrStart,1).hex()))
for i in range(addrStart,addrEnd+1):
if get_bytes(i,1).hex()=="eb":
if get_bytes(i+1,1).hex()=="ff":
num+=1
patch_byte(i,0x90)
print("D0ne!!,已清除%d"%(num),"个Flower")
addrStart=0x4011E0
addrEnd=0x401A3B
num=0
#print((get_bytes(addrStart,1).hex()))
for i in range(addrStart,addrEnd+1):
if get_bytes(i,1).hex()=="74":
if get_bytes(i+1,1).hex()=="fa":
if get_bytes(i+2,1).hex()=="e8":
num+=1
patch_byte(i,0x90)
patch_byte(i+1,0x90)
patch_byte(i+2,0x90)
print("D0ne!!,已清除%d"%(num),"个Flower")
去除完后对main先U后P,让IDA重新识别函数。
输入的长度应该是134(看别人博客直接用z3解了)
感觉这段运行到最后也不是正确的flag。
只能慢慢查看函数。
没点几个函数就发现windows的seh了。(汇编窗口更加明显)
补充一下seh的特征
mov [ebp+ms_exc.registration.TryLevel], 0 ; try块开始
mov [ebp+ms_exc.registration.TryLevel], 0FFFFFFFEh;结束异常
call了 sub_E311E0,直接跟进
这里其实也有一个异常处理,但是IDA没给注释。
图片右下角的hjlk其实也在提示我们,这题另有玄机。
用keypatch直接jmp到loc_E32178
F5编译后
1!5!~~ 这不是走迷宫吗。还是看看远处的hjkl吧。对应方向也很轻松的看出来。
异或生成地图,直接丢写的py脚本了。
s1=[ 0x00000044, 0x00000124, 0x000002BD, 0x0000033E, 0x00000432, 0x0000059D, 0x0000068F, 0x00000753,
0x000008CC, 0x0000094F, 0x00000A8D, 0x00000B2C, 0x00000C7C, 0x00000DF2, 0x00000EBA, 0x00000F30,
0x0000100D, 0x000011C7, 0x00001257, 0x00001319, 0x00001491, 0x000000F4, 0x000001E7, 0x00000229,
0x0000034F, 0x000004EE, 0x00000547, 0x0000067C, 0x000007D8, 0x000008F8, 0x000009D8, 0x00000A79,
0x00000BD1, 0x00000C7A, 0x00000D32, 0x00000E82, 0x00000FD9, 0x000010DF, 0x00001120, 0x000012D6,
0x000013EE, 0x0000145F, 0x00000027, 0x0000016C, 0x00000265, 0x000003B7, 0x0000049F, 0x0000054B,
0x000006C8, 0x000007DF, 0x00000866, 0x0000099F, 0x00000A0C, 0x00000B2D, 0x00000C0C, 0x00000DBF,
0x00000E19, 0x00000F83, 0x000010F1, 0x00001169, 0x0000125C, 0x000013A3, 0x000014AE, 0x0000000C,
0x00000164, 0x00000274, 0x0000033D, 0x000004BD, 0x00000582, 0x00000696, 0x00000784, 0x00000846,
0x000009AB, 0x00000ABA, 0x00000BBA, 0x00000CFC, 0x00000DB7, 0x00000E18, 0x00000F96, 0x0000106C,
0x00001138, 0x00001267, 0x000013F5, 0x00001481, 0x00000072, 0x0000010E, 0x0000022C, 0x000003AF,
0x00000489, 0x000005B3, 0x000006B3, 0x000007C5, 0x0000080B, 0x0000091E, 0x00000A3E, 0x00000BF8,
0x00000C73, 0x00000D75, 0x00000EE2, 0x00000F5A, 0x00001038, 0x0000119A, 0x000012E9, 0x0000133F,
0x00001487, 0x000000AA, 0x00000137, 0x00000298, 0x00000346, 0x000004D3, 0x000005D5, 0x0000069E,
0x00000711, 0x000008B8, 0x0000097D, 0x00000AD9, 0x00000BD3, 0x00000CC7, 0x00000D18, 0x00000E51,
0x00000FB7, 0x000010CB, 0x000011FC, 0x00001274, 0x00001396, 0x00001441, 0x00000082, 0x000001A5,
0x0000025F, 0x000003E8, 0x00000487, 0x00000528, 0x000006F7, 0x00000797, 0x000008F3, 0x000009AC,
0x00000ADC, 0x00000B65, 0x00000C73, 0x00000DE6, 0x00000EBC, 0x00000FCD, 0x000010C3, 0x000011AB,
0x0000123F, 0x000013A0, 0x00001450, 0x00000043, 0x00000122, 0x000002AD, 0x000003CD, 0x0000042D,
0x00000537, 0x00000692, 0x000007DB, 0x00000810, 0x00000936, 0x00000A49, 0x00000B65, 0x00000C3E,
0x00000DA3, 0x00000E1B, 0x00000F95, 0x000010E6, 0x000011AF, 0x00001228, 0x000013B5, 0x00001448,
0x0000002F, 0x0000015B, 0x0000024E, 0x0000032A, 0x000004D2, 0x0000053C, 0x000006D6, 0x000007C9,
0x0000082F, 0x00000957, 0x00000AE2, 0x00000B26, 0x00000C98, 0x00000D57, 0x00000EC3, 0x00000FC2,
0x000010DE, 0x00001118, 0x000012AB, 0x00001386, 0x0000144F, 0x000000D5, 0x000001C9, 0x000002F3,
0x000003E7, 0x000004C6, 0x000005C0, 0x000006C2, 0x000007D1, 0x000008F0, 0x000009B0, 0x00000A1D,
0x00000B3D, 0x00000C2A, 0x00000D62, 0x00000E64, 0x00000F20, 0x000010FF, 0x000011EA, 0x00001217,
0x000013F0, 0x000014F6, 0x000000E0, 0x000001F0, 0x000002E2, 0x0000037B, 0x00000456, 0x000005DE,
0x000006E6, 0x00000772, 0x000008DF, 0x00000970, 0x00000A29, 0x00000B16, 0x00000C62, 0x00000DFB,
0x00000E33, 0x00000F6A, 0x000010C8, 0x000011B2, 0x00001271, 0x000013F8, 0x000014C8, 0x000000A9,
0x00000192, 0x0000026F, 0x00000342, 0x000004A7, 0x00000533, 0x0000065F, 0x00000707, 0x000008B9,
0x00000900, 0x00000ADC, 0x00000B90, 0x00000C4C, 0x00000D7B, 0x00000E81, 0x00000FC7, 0x00001004,
0x0000118D, 0x000012C0, 0x00001375, 0x000014EB, 0x000000A7, 0x00000147, 0x000002C6, 0x00000374,
0x0000044F, 0x000005EE, 0x0000066D, 0x00000719, 0x00000807, 0x00000970, 0x00000A07, 0x00000BD5,
0x00000C18, 0x00000D4D, 0x00000EFE, 0x00000F20, 0x00001021, 0x0000116C, 0x00001218, 0x000013CC,
0x0000144F, 0x000000A8, 0x00000117, 0x000002CA, 0x0000033F, 0x000004C5, 0x00000585, 0x000006BB,
0x0000073A, 0x000008C8, 0x0000095A, 0x00000A8D, 0x00000B2F, 0x00000CC6, 0x00000DD8, 0x00000EFD,
0x00000F73, 0x000010F8, 0x00001168, 0x00001280, 0x0000137E, 0x00001466, 0x000000AA, 0x00000194,
0x000002E0, 0x000003A2, 0x000004B4, 0x0000057F, 0x00000640, 0x000007D0, 0x00000865, 0x00000986,
0x00000A38, 0x00000B13, 0x00000C7C, 0x00000DBF, 0x00000EFE, 0x00000F95, 0x00001066, 0x00001117,
0x000012BE, 0x00001373, 0x000014E4, 0x000000F9, 0x0000015F, 0x0000026C, 0x000003DF, 0x00000434,
0x00000569, 0x00000658, 0x00000768, 0x000008B4, 0x00000976, 0x00000A56, 0x00000B68, 0x00000CBF,
0x00000DCB, 0x00000E81, 0x00000FE7, 0x00001062, 0x00001196, 0x00001233, 0x000013FE, 0x00001486,
0x000000E7, 0x000001AF, 0x00000205, 0x00000371, 0x00000482, 0x000005F0, 0x00000670, 0x0000072E,
0x00000849, 0x00000925, 0x00000A5B, 0x00000B0E, 0x00000C7F, 0x00000D75, 0x00000EF4, 0x00000F61,
0x0000101D, 0x0000116B, 0x0000127E, 0x00001382, 0x00001404, 0x0000004D, 0x0000015C, 0x0000027F,
0x0000033F, 0x00000442, 0x000005B6, 0x0000064D, 0x00000780, 0x0000086B, 0x000009DC, 0x00000AF1,
0x00000B79, 0x00000C66, 0x00000D6E, 0x00000E9D, 0x00000F23, 0x0000107B, 0x00001126, 0x000012D5,
0x0000133F, 0x000014AE, 0x0000007D, 0x000001AD, 0x000002BB, 0x000003A1, 0x00000473, 0x0000054E,
0x000006C0, 0x000007D0, 0x0000083F, 0x000009DA, 0x00000AE6, 0x00000BA9, 0x00000CA0, 0x00000DC3,
0x00000E30, 0x00000F8E, 0x00001066, 0x000011CD, 0x0000124B, 0x00001361, 0x000014B8, 0x000000EE,
0x0000016D, 0x00000275, 0x0000033C, 0x00000473, 0x000005A8, 0x00000679, 0x00000759, 0x0000080B,
0x000009B4, 0x00000AC7, 0x00000B03, 0x00000C07, 0x00000DAE, 0x00000E82, 0x00000FF8, 0x00001050,
0x000011DF, 0x00001261, 0x000013A0, 0x000014D5, 0x00000053, 0x000001B7, 0x000002D8, 0x000003B8,
0x00000478, 0x000005BC, 0x000006CC, 0x000007DE, 0x000008C6, 0x00000990, 0x00000A3F, 0x00000B21,
0x00000CBF, 0x00000DBB, 0x00000EDC, 0x00000FB1, 0x0000103B, 0x0000116B, 0x0000126B, 0x000013E0,
0x00001434]
s2=[0x45, 0x24, 0xBD, 0x3E, 0x32, 0x9D, 0x8F, 0x53, 0xCC, 0x4F, 0x8D, 0x2C, 0x7C, 0xF2, 0xBA, 0x30, 0x0D, 0xC7, 0x57, 0x19, 0x91, 0xF4, 0xE6, 0x28, 0x4F, 0xEE, 0x47, 0x7C, 0xD8, 0xF8, 0xD8, 0x79, 0xD1, 0x7A, 0x32, 0x82, 0xD9, 0xDF, 0x20, 0xD6, 0xEF, 0x5E, 0x24, 0x6E, 0x67, 0xB4, 0x9D, 0x49, 0xCA, 0xDD, 0x64, 0x9D, 0x0E, 0x2F, 0x0E, 0xBD, 0x1B, 0x81, 0xF3, 0x6B, 0x5F, 0xA1, 0xAC, 0x0E, 0x66, 0x76, 0x3F, 0xBF, 0x80, 0x94, 0x86, 0x44, 0xA9, 0xB8, 0xB8, 0xFE, 0xB5, 0x1A, 0x94, 0x6F, 0x3B, 0x64, 0xF6, 0x82, 0x76, 0x0A, 0x28, 0xAB, 0x8D, 0xB7, 0xB7, 0xC1, 0x0F, 0x1A, 0x3A, 0xFC, 0x77, 0x71, 0xE6, 0x5F, 0x3C, 0x9F, 0xEC, 0x3A, 0x83, 0xAF, 0x32, 0x9D, 0x43, 0xD6, 0xD0, 0x9B, 0x14, 0xBD, 0x78, 0xDC, 0xD6, 0xC2, 0x1D, 0x54, 0xB3, 0xCE, 0xF8, 0x71, 0x92, 0x44, 0x85, 0xA2, 0x58, 0xEF, 0x80, 0x2F, 0xF0, 0x90, 0xF4, 0xAB, 0xDB, 0x63, 0x74, 0xE1, 0xBB, 0xCA, 0xC5, 0xAC, 0x39, 0xA7, 0x56, 0x45, 0x25, 0xAA, 0xCA, 0x2A, 0x30, 0x95, 0xDC, 0x17, 0x31, 0x4F, 0x62, 0x39, 0xA4, 0x1C, 0x93, 0xE1, 0xA9, 0x2F, 0xB3, 0x4F, 0x26, 0x53, 0x47, 0x23, 0xDB, 0x34, 0xDE, 0xC1, 0x27, 0x5F, 0xEB, 0x2E, 0x91, 0x5E, 0xCA, 0xCB, 0xD6, 0x11, 0xA3, 0x8F, 0x47, 0xDD, 0xC0, 0xFB, 0xEE, 0xCF, 0xC9, 0xCA, 0xD9, 0xF8, 0xB9, 0x15, 0x34, 0x23, 0x6B, 0x6D, 0x28, 0xF6, 0xE2, 0x1E, 0xF8, 0xFF, 0xEB, 0xFB, 0xE9, 0x70, 0x5C, 0xD4, 0xED, 0x78, 0xD4, 0x7A, 0x22, 0x1C, 0x69, 0xF1, 0x39, 0x61, 0xC2, 0xB9, 0x7B, 0xF3, 0xC2, 0xA2, 0x99, 0x64, 0x48, 0xAC, 0x38, 0x55, 0x0C, 0xB3, 0x0B, 0xD6, 0x9B, 0x46, 0x70, 0x8B, 0xCD, 0x0F, 0x87, 0xCB, 0x7F, 0xE0, 0xAB, 0x4A, 0xCB, 0x79, 0x43, 0xE2, 0x60, 0x15, 0x0A, 0x7C, 0x0A, 0xD9, 0x15, 0x41, 0xF3, 0x2C, 0x2C, 0x61, 0x14, 0xC1, 0x43, 0xA5, 0x1A, 0xC7, 0x33, 0xC9, 0x89, 0xB7, 0x37, 0xC4, 0x57, 0x81, 0x23, 0xCA, 0xD4, 0xF1, 0x7E, 0xF4, 0x65, 0x8D, 0x72, 0x6B, 0xA4, 0x9A, 0xEE, 0xAC, 0xBA, 0x71, 0x4E, 0xDE, 0x6A, 0x88, 0x36, 0x1D, 0x72, 0xB1, 0xF0, 0x9B, 0x69, 0x19, 0xB0, 0x7C, 0xEA, 0xF7, 0x51, 0x62, 0xD1, 0x3A, 0x67, 0x56, 0x66, 0xBA, 0x79, 0x59, 0x66, 0xB1, 0xC5, 0x8F, 0xE9, 0x6C, 0x99, 0x3C, 0xF0, 0x89, 0xF6, 0xBF, 0x15, 0x61, 0x92, 0xE0, 0x60, 0x3E, 0x59, 0x35, 0x4B, 0x1F, 0x6F, 0x65, 0xE4, 0x71, 0x0D, 0x7B, 0x6E, 0x93, 0x14, 0x5D, 0x4C, 0x6F, 0x2F, 0x52, 0xA6, 0x5D, 0x90, 0x7B, 0xCC, 0xE1, 0x69, 0x77, 0x7E, 0x8D, 0x33, 0x6B, 0x37, 0xC4, 0x2F, 0xBF, 0x6F, 0xBF, 0xA8, 0xB3, 0x61, 0x5C, 0xD2, 0xC2, 0x2D, 0xC8, 0xF4, 0xBB, 0xB2, 0xD0, 0x22, 0x9C, 0x75, 0xDF, 0x59, 0x72, 0xAA, 0xFD, 0x7E, 0x67, 0x2E, 0x61, 0xBA, 0x6B, 0x4B, 0x19, 0xA6, 0xD5, 0x11, 0x15, 0xBC, 0x91, 0xEB, 0x42, 0xCC, 0x72, 0xB2, 0xC6, 0x47, 0xA3, 0xCC, 0xAC, 0x6C, 0xA8, 0xD8, 0xCA, 0xD2, 0x84, 0x2B, 0x35, 0xAB, 0xAF, 0xC8, 0xA5, 0x2F, 0x7F, 0x7F, 0xF5, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
for i in range(21):
print("[",end="")
for j in range(21):
if(j!=20):
print(s1[i*21+j]^s2[i*21+j]^i^(j<<8),end=',')
else :
print(s1[i*21+j]^s2[i*21+j]^i^(j<<8),end='')
print("]")
print()
得到地图后,还好我在ACM待过一个多学期,写个dfs还是会的,直接得到答案。
maze=[[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
[1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0],
[1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,1,0,1,0],
[1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0,1,0],
[1,0,1,1,1,0,0,0,0,0,1,0,1,1,1,1,0,1,0,1,0],
[1,0,1,0,0,0,1,1,1,0,1,0,0,0,0,1,0,1,0,1,0],
[1,1,1,1,0,0,1,0,1,0,1,0,1,0,0,1,0,1,0,1,0],
[0,0,0,1,0,0,1,0,1,0,1,0,1,0,1,1,0,1,0,1,0],
[0,1,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,0],
[0,0,0,1,1,1,1,0,1,0,1,1,1,1,1,0,1,0,0,1,0],
[0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0],
[1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,1,0],
[1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0],
[1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,0,0,1,0],
[0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0],
[0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1]]
usedmap=[[0 for i in range(len(maze))]for i in range(len(maze[0]))]
sti=0
stj=0
edi=20
edj=20
flag=''
def dfs(x,y):
global flag
if x==edi and y==edj:
print(flag)
return
if x+1<21 and maze[x+1][y]==1 and usedmap[x+1][y]==0:
usedmap[x][y]=1
flag+='j'
dfs(x+1,y)
flag=flag[:-1]
usedmap[x][y]=0
if x-1>=0 and maze[x-1][y]==1 and usedmap[x-1][y]==0:
usedmap[x][y]=1
flag+='h'
dfs(x-1,y)
flag=flag[:-1]
usedmap[x][y]=0
if y+1<21 and maze[x][y+1]==1 and usedmap[x][y+1]==0:
usedmap[x][y]=1
flag+='l'
dfs(x,y+1)
flag=flag[:-1]
usedmap[x][y]=0
if y-1>=0 and maze[x][y-1]==1 and usedmap[x][y-1]==0:
usedmap[x][y]=1
flag+='k'
dfs(x,y-1)
flag=flag[:-1]
usedmap[x][y]=0
dfs(sti,stj)
#jjjllllllllllllllljjjjjjjjkjjkkkkhhhhhhhkkkkkkkkkkjjjjllljjjlllhhhhlljjjjjjkkkkkkkkjjlllllllllllhhlllllhhhlhhhhhhhhlljjjjjjjjjjjjjjjjl
'''
for i in range(len(maze)):
for j in range(len(maze[0])):
print(maze[i][j],end='')
print()
'''
路径md5加密套个flag
总结
异常处理甚至还能作为反调试用,自己在调试的时候直接被中止了。因为触发异常后就由程序注册的异常处理函数接管, 而如果没有在异常处理程序入口设下断点的话, 程序就容易跑飞。
评论区