03_DES源码分析
03_DES源码分析一、DES加密步骤 这里以一个分组为例:
明文为:0123456789ABCDEF(这个是HEX编码之后的数据)
密钥为:133457799BBCDFF1
1. 子密钥生成 首先将密钥转成二进制:
100110001 00110011 00110011 00110100 00110101 00110111 00110111 00111001 00111001 01000010 01000010 01000011 01000100 01000110 01000110 00110001
根据PC1表进行对密钥的重新排列:
1234567int PC1_Table[56] = { 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, ...
02_SHA1源码分析
SHA1算法源码分析一、SHA1明文处理1. C调用SHA1哈希方法12345678SHA1Context ctx;SHA1Context* pCtx = &ctx;SHA1Reset(pCtx);SHA1Input(pCtx, (const uint8_t*)"Hello SHA1", strlen("Hello SHA1"));uint8_t digst[SHA1HashSize];SHA1Result(pCtx, digst);for (int i = 0; i < SHA1HashSize; i++) printf("%02x", digst[i]);
2. 明文处理SHA1的数据填充方式与MD5的一样:
在原始数据后添加一个1比特
在1比特后填充比特0,使其长度接近但不超过448位
最后使用64位二进制数表示原始数据长度,附件在末尾
填充当中与MD5唯一的区别就是:64位数据长度按照大端序存放
二、SHA1主要流程1. SHA1Context结构体12345678910typedef s ...
01_MD5源码分析
01_MD5源码分析一、MD5明文处理1. C实现的MD5算法使用123456MD5_CTX context;MD5Init(&context);unsigned char* plainText = (unsigned char *) "xiaojianbang";MD5Update(&context, plainText, strlen(reinterpret_cast<const char *>(plainText)));unsigned char result[16];MD5Final(&context, result);
2. MD明文处理大致过程 首先对明文进行hex编码:xiaojianbang ==> 78 69 61 6f 6a 69 61 6e 62 61 6e 67。然后会将明文填充到448bit,填充的时候先填一个比特位,再填0,将明文扩展到448bit。
接着就是附加消息长度:用64bit表示消息长度,这里的长度是指明文的比特位数量,然后将长度转小端序之后拼接。
最后明文会处理成以下 ...
2025-11-week3
week3刷题1. [2019红帽杯]childRE 下载题目后直接IDA打开,然后分析main的反编译伪代码,将一些变量函数名修复一下:
整个main函数有两部分组成,首先就是输入input,然后将输入经过XMMI2_FP_Emulation这个函数将input做相关操作然后存到v4中,再使用sub_1400015C0进一步处理,将结果存放到v5。
第二部分就是将v5通过UnDecorateSymbolName函数生成的字符串存放到outputString当中,用outputString当中的元素当作一个表的索引与其他两个表进行比较,这个就是check部分。
那么先来解这个check部分就能解出来outputString这个字符串是什么了。这里的check当中使用的%23, /23其实就是带余除法,那么只需要将这两个索引*23 + 余数就是outputString的元素:
12345678910111213141516mapper = bytes.fromhex("31 32 33 34 35 36 37 38 39 30 2D 3D 21 40 23 24 ...
2025-11-week2.md
week2刷题1. [Zer0pts2020]easy strcmp 下载后直接IDA打开题目,结构非常的简单,直接看main函数
只有一个赤裸裸的strcmp,进去看看有什么操作:
此时这个strcmp大概率就是被hook了。
在ELF当中,init会比main先执行,可以看看init里面的函数做了什么:
也就是这三个函数:
逐个查看,发现在sub_795当中hook的strcmp:
而hook函数就是sub_6EA,接下来看看这个函数怎么回事:
12345678910111213__int64 __fastcall sub_6EA(__int64 a1, __int64 a2){ int i; // [rsp+18h] [rbp-8h] int v4; // [rsp+18h] [rbp-8h] int j; // [rsp+1Ch] [rbp-4h] for ( i = 0; *(_BYTE *)(i + a1); ++i ) ; v4 = (i >> 3) + 1; for ( j = 0; j < v4; ++j ) ...
week1 刷题
week1 刷题1. [GXYCTF2019]simple CPP IDA载入直接分析,这个程序的主要加密逻辑有几块:
第一块是一个异或,和key进行异或
第二部分是将8个字符拼成一个QWORD,然后存放到v20当中
最后就是将v20的值拿出来计算然后进行比较判断。在最后这个加密当中,运用了一大堆的运算,那么z3是最好的方式,直接z3求解即可。
这里有一个注意的地方是,我们并不知道输入有多长,只知道最后比较的长度是32字节,所以这里的z3需要从分组之后开始求解。求解出来后再回推input。这里试了一下从开头写z3到结尾会导致解出来的值不太一样。
exp:
123456789101112131415161718192021222324252627282930313233343536373839404142from z3 import*f1, f2, f3, f4 = BitVecs('f1 f2 f3 f4', 64)s = Solver()s.add(f3 & (~f1) == 0x11204161012)s.add((f3 & ...
2024极客大挑战 复现
2024极客大挑战REcpp_flower思路知识点这题就是一个纯花指令,主要有两个部分的花指令特征:
jnz/jz addr+1
就像下面这种:
patch方法可以直接将第一个jz改成jmp,再重新分析成代码:
第二种就是call一个函数,然后修改ret_addr:
就像这种,这里大致功能就是jmp到0x419db3。
patch方法就是直接改成jmp到指定位置即可。
修复完成后逻辑如下:
大致意思就是先srand(0x7de9),然后每个随机数模255和input异或,最后和unk_422c30比较。
EXP123456789101112131415void cpp_flower(){ char enc[] = { 0x3E, 0x98, 0xEB, 0x26, 0x25, 0x8E, 0x25, 0xE5, 0x86, 0xC8, 0x3F, 0x98, 0xC8, 0xDE, 0x52, 0x44,0xA0, 0xCB, 0x2B, 0x2A, 0x3C, 0xAA, 0xBE, 0xCB, 0x88, 0x ...
1.导入表隐藏
首先得先了解一个结构:
1.TEB、PEB
TEB:
TEB线程环境块:每个线程都有一个对应的TEB
PEB:
PEB进程环境块:每个进程在创建时都会有一个对应的PEB,它储存了该进程的全局状态和环境信息
这里不进行详细介绍,只了解需要用到的东西。
(1)TEB结构体
32位操作系统下,TEB结构体中偏移0x30的值是PEB结构体的地址,指向PEB结构体。我们可以通过这个获取到PEB的地址
(2)PEB结构体PEB 结构体中用到的就是这个PPEB_LDR_DATA Ldr;,偏移量是0xC,用这个可以直接获取到LDR_DATA结构体的地址。
(3)PEB_LDR_DATA结构体我们来看看这个PEB_LDR_DATA结构体是什么:
12345678typedef struct _PEB_LDR_DATA { ULONG Length; BOOL Initialized; PVOID SsHandle; LIST_ENTRY InLoadOrderMod ...
RE刷题记录 —— 01
1. [SUCTF2019]hardcpp这题是一道非常经典的混淆题目,将附件下载后我们来查看这个附件的信息:
die非常的智能已经分析出来的用来LLVM的保护器了,然后文件是elf 64位文件。直接用ida64打开,打开后直接先看一眼main函数,发现这个流程图非常的恶心,再结合之前die给出的保护器就可以判断这个用到的是ollvm的保护了:
这个ollvm的开始就是main函数,此时我们可以通过deflat来处理掉这些个控制流平坦化。(deflat具体安装步骤自行前往网上查找),接着就是直接使用deflat.py来去掉这个控制流平坦化,通过汇编代码找到函数开始的地址为0x4007E0:
直接启动defluat.py:
1python deflat.py -f ../hardCpp --addr 0x4007e0
-f:后面跟的是要修改的文件的路径
--addr:文件修改的起始地址(ida中的地址)
成功后就会生成一个hardCpp_recovered文件。此时再通过ida打开这个文件就可以看到已经去掉了控制流平坦化了,接下来就可以分析了。
函数开始 ...
22.Inline_Hook
引入
根据上节课IAT HOOK结尾的局限性分析,自己写的函数,或者是通过LoadLibrary进来的函数在IAT 表中都是不存在的。这时候我们就需要用到Inline HOOK
Inline HOOK(内联HOOK),CE工具中的代码注入用到的就是这种HOOK。原理就是,在HOOK点修改指令,跳转到我们的函数位置,然后此时就可以获取到寄存器,堆栈信息。执行完我们自己的代码后再跳转回到原来的位置执行。
注意事项
在制作Inline hook的过程中有不少需要注意的地方:
当我们在跳转的时候可以用E8(Call),E9(Jmp)这些后面跟的地址都是需要通过公式计算的。公式:X = 要跳转到的地址 - 5 - 当前地址(X就是跳转指令后面的值)
当我们HOOK插入跳转指令的时候会修改掉一些指令,但是当前函数还没有执行这几条指令,所以在我们的函数执行完成之前还得调用回这几条指令
当我们跳转到我们自己的函数区域时可能会对堆栈、寄存器做修改,这时候就得在执行这些操作之前保存寄存器的值,在完成操作后恢复寄存器和堆栈
这里还有一个要注意的地方就是想要直接获取到自定义函数的函数首地址不能直接 ...
