md5在ida中的识别

ida中 识别md5 ,先右键转为hex 或者按h

_DWORD *__fastcall MD5Init(_DWORD *result)
{
  *result = 0;
  result[1] = 0;
  result[2] = 1732584193;
  result[3] = -271733879;
  result[4] = -1732584194;
  result[5] = 271733878;
  return result;
}

在ida中当然也可以使用搜索
search imdate-value 搜索立即数 0x67452301; 这是上面的init中的state一个数···

 v2 = __ROR4__((v66 & ~v99 | v83 & v99) + v133 + v116 - 0x28955B88, 25);
 __ROR4__ 是循环右移 
 鼠标右键 invert  sign可以改正一些纠正一下负号    3 + 0x242070DB

数值类型转换

int __fastcall MD5Final(unsigned int *a1, unsigned __int8 *a2)
{
  unsigned int v3; // [sp+8h] [bp-28h]
  unsigned int v4; // [sp+10h] [bp-20h]
  unsigned __int8 v7[8]; // [sp+1Ch] [bp-14h] BYREF

  v4 = (*a1 >> 3) & 0x3F;
  if ( v4 > 0x37 )
    v3 = 120 - v4;
  else
    v3 = 56 - v4;
  MD5Encode(v7, a1, 8u);
  MD5Update(a1, PADDING, v3);
  MD5Update(a1, v7, 8);
  MD5Encode(a2, a1 + 2, 0x10u);
  return _stack_chk_guard;
//这是识别的final   ,计算长度,压入padding放入长度 拼接 
====》padding
.data:00006000                 AREA .data, DATA
.data:00006000                 ; ORG 0x6000
.data:00006000                 EXPORT PADDING
.data:00006000 PADDING         DCD dword_80            ; DATA XREF: LOAD:00000520↑o
.data:00006000                                         ; MD5Final(MD5_CTX *,uchar *)+5A↑o ...
.data:00006004                 ALIGN 0x40
.data:00006040                 DCD unk_6044

dcd 指定是低位的  
按D 会转  dcb   ====>
6000                 EXPORT PADDING
.data:00006000 PADDING         DCB 0x80                ; DATA XREF: LOAD:00000520↑o
.data:00006000                                         ; MD5Final(MD5_CTX *,uchar *)+5A↑o ...
.data:00006001                 DCB    0
.data:00006002                 DCB    0
.data:00006003                 DCB    0
.data:00006004                 ALIGN 0x40
.data:00006040                 DCD unk_6044
dcq代表八个字节

ida的算法识别 md5

某个libwtf.so的算法
image.png
这个final 中的update 中的update padding
thumb 有两个字节 有四个字节 ,arm 是四个字节

find hash 的使用

findhash.xmlfindhash.py 放到ida plugins 文件夹下
用之前写的revdemo来试一下
点击 plugins/findhash

Python 3.11.6 (tags/v3.11.6:8b6ee5b, Oct  2 2023, 14:57:12) [MSC v.1935 64 bit (AMD64)] 
IDAPython 64-bit v7.4.0 final (serial 0) (c) The IDAPython Team <idapython@googlegroups.com>
---------------------------------------------------------------------------------------------
Propagating type information...
Function argument information has been propagated
lumina: Invalid remote certificate
The initial autoanalysis has been finished.
findHash (v0.1) plugin has been loaded.
这个脚本只考虑了32位SO的反编译代码,64位未适配。
***************************在二进制文件中检索hash算法常量************************************
0x4b100:padding used in hashing algorithms (0x80 0 ... 0)
0x1e978:函数MD5Init(MD5_CTX *)疑似哈希函数,包含初始化魔数的代码。
0x1eb98:函数MD5Transform(uint *,uchar *)疑似哈希函数运算部分。
0x20634:函数MD5InitMagic(MD5_CTX *)疑似哈希函数,包含初始化魔数的代码。
0x2c114:函数sub_2C114疑似哈希函数,包含初始化魔数的代码。
0x317dc:函数sub_317DC疑似哈希函数,包含初始化魔数的代码。
0x31f18:函数sub_31F18疑似哈希函数,包含初始化魔数的代码。
0x330dc:函数sub_330DC疑似哈希函数,包含初始化魔数的代码。
0x33dcc:函数sub_33DCC疑似哈希函数,包含初始化魔数的代码。
0x33fdc:函数sub_33FDC疑似哈希函数,包含初始化魔数的代码。
0x3436c:函数sub_3436C疑似哈希函数,包含初始化魔数的代码。
0x3b248:函数sub_3B248疑似哈希函数,包含初始化魔数的代码。
0x3bb84:函数sub_3BB84疑似哈希函数,包含初始化魔数的代码。
***************************存在以下可疑的字符串************************************
0x4f3b:Java_com_koohai_revdemo_utils_EncryptCUtils_md5
0x4fe4:md5(std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>> const&)
0x5189:Java_com_koohai_revdemo_utils_EncryptCUtils_md5_1magic
0x51c0:md5magic(std::__ndk1::basic_string<char,std::__ndk1::char_traits<char>,std::__ndk1::allocator<char>> const&)
生成对应的hook脚本如下:
frida -UF -l E:\Coding\XposedDemo\app-debug\lib\arm64-v8a\librevdemo_findhash_1719082084.js
***********************************************************************************
花费 40.45436191558838 秒,因为会对全部函数反编译,所以比较耗时间哈

只能说插件强大,把之前的md5 和md5_magic都识别了
插件自动生成的hook代码如下:

function hook_suspected_function(targetSo) {
    const funcs = [['MD5Init(MD5_CTX *)', '函数MD5Init(MD5_CTX *)疑似哈希函数,包含初始化魔数的代码。', '0x1e978'], ['MD5Transform(uint *,uchar *)', '函数MD5Transform(uint *,uchar *)疑似哈希函数运算部分。', '0x1eb98'], ['MD5InitMagic(MD5_CTX *)', '函数MD5InitMagic(MD5_CTX *)疑似哈希函数,包含初始化魔数的代码。', '0x20634'], ['sub_2C114', '函数sub_2C114疑似哈希函数,包含初始化魔数的代码。', '0x2c114'], ['sub_317DC', '函数sub_317DC疑似哈希函数,包含初始化魔数的代码。', '0x317dc'], ['sub_31F18', '函数sub_31F18疑似哈希函数,包含初始化魔数的代码。', '0x31f18'], ['sub_330DC', '函数sub_330DC疑似哈希函数,包含初始化魔数的代码。', '0x330dc'], ['sub_33DCC', '函数sub_33DCC疑似哈希函数,包含初始化魔数的代码。', '0x33dcc'], ['sub_33FDC', '函数sub_33FDC疑似哈希函数,包含初始化魔数的代码。', '0x33fdc'], ['sub_3436C', '函数sub_3436C疑似哈希函数,包含初始化魔数的代码。', '0x3436c'], ['sub_3B248', '函数sub_3B248疑似哈希函数,包含初始化魔数的代码。', '0x3b248'], ['sub_3BB84', '函数sub_3BB84疑似哈希函数,包含初始化魔数的代码。', '0x3bb84']];
    for (var i in funcs) {
        let relativePtr = funcs[i][2];
        let funcPtr = targetSo.add(relativePtr);
        let describe = funcs[i][1];
        let handler = (function() {
        return function(args) {
            console.log("\n");
            console.log(describe);
            console.log(Thread.backtrace(this.context,Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join("\n"));
        };
        })();
    //Interceptor.attach(funcPtr, {onEnter: handler});
    hook_native_addr(funcPtr)  
    //替换为下面的函数 ,可以打印参数。 
}
}
//他会自己给出疑似的地址,就直接在so进行hook    MD5InitMagic 这个自己魔改了初始址 也被发现了 


对于这个算法,可以稍微改进一下,让他生成的js 加上打印参数 ,MD5的话 transfrom 第二个参数 的64个字节 就是明文,拼起来就是完整的铭文。
//ptr(addr)主要用于呈现地址本身的易读形式,
//而hexdump(addr)则用于展示该地址指向的内存区域的详细十六进制内容

function print_arg(addr){
	var module = Process.findRangeByAddress(addr);
	if(module != null){
		return hexdump(addr) + "\n";
	}else{
		return ptr(addr) + "\n";
	}
}

function hook_native_addr(funcPtr){
	var module = Process.findModuleByAddress(funcPtr);
	Interceptor.attach(funcPtr, {
		onEnter: function(args){
      console.log(Thread.backtrace(this.context,Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join("\n"));
       
			this.args0 = args[0];
			this.args1 = args[1];
			this.args2 = args[2];
			this.args3 = args[3];
			this.logs = [];
			this.logs.push("call " + module.name + "!" + ptr(funcPtr).sub(module.base) + "\n");
			this.logs.push("this.args0 onEnter: " + print_arg(this.args0));
			this.logs.push("this.args1 onEnter: " + print_arg(this.args1));
			this.logs.push("this.args2 onEnter: " + print_arg(this.args2));
			this.logs.push("this.args3 onEnter: " + print_arg(this.args3));
			
		}, onLeave: function(retval){
			this.logs.push("this.args0 onLeave: " + print_arg(this.args0));
			this.logs.push("this.args1 onLeave: " + print_arg(this.args1));
			this.logs.push("this.args2 onLeave: " + print_arg(this.args2));
			this.logs.push("this.args3 onLeave: " + print_arg(this.args3));
			this.logs.push("retval onLeave: " + retval + "\n");
			console.log(this.logs);
		}
	});
}
//这里可以打印参数。 在离开的时候一起打印 
// 参数可能是地址 或者数值 明文指针/长度  需要判断。 地址的话就打印整个内容 。数值就打印数值。
//ptr(addr)主要用于呈现地址本身的易读形式,
//而hexdump(addr)则用于展示该地址指向的内存区域的详细十六进制内容

===》
frida-trace 能获取到所有地址
把地址放到上面的so hook中,就可以hook所有函数 加参数
//更多代码,更多内容请移步公众号一起请添加图片描述
学习,同篇笔记会有更新喔

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sugar椰子皮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值