字符串搜索一把梭,hook libc.so系统库函数
在安卓逆向过程,常常遇见一些加密字段没有写在java层,写在native层通过加密算法动态生成,但是只要是一个正常算法的生成,就一定会调用系统的库函数,故写了一段hook系统库函数的代码用于分析加密字符串的生成😀
var target = "com";
function hook_memcpy() {
var libc = Module.findBaseAddress('libc.so');
var memcpAddress = Module.findExportByName('libc.so', 'memcpy');
if (!memcpAddress) {
console.log('memcpy not found');
return;
}
Interceptor.attach(memcpAddress, {
onEnter: function(args) {
// 需要确保 args[1] 是有效的指针
if (args[1] && args[1].isNull() === false) {
var srcCString = args[1].readCString();
if (srcCString && srcCString.includes(target)) {
console.log('memcpy called from:\n' +
Thread.backtrace(this.context, Backtracer.ACCURATE)
.map(DebugSymbol.fromAddress).join('\n')); // 打印调用栈
console.log('src: ' + srcCString); // 源地址
console.log('dest: ' + args[0]); // 目标地址
console.log('size: ' + args[2].toInt32() + '\n'); // 拷贝大小
}
}
},
onLeave: function(retval) {
// console.log('memcpy returned: ' + retval);
}
});
}
function hook_strcmp() {
var libc = Module.findBaseAddress('libc.so');
var memcmpAddress = Module.findExportByName('libc.so', 'memcmp');
if (!memcmpAddress) {
console.log('memcmp not found');
return;
}
Interceptor.attach(memcmpAddress, {
onEnter: function(args) {
// args[0] 和 args[1] 是待比较的内存块,args[2] 是要比较的字节数
var ptr1 = args[0]; // 第一个内存块的指针
var ptr2 = args[1]; // 第二个内存块的指针
var numBytes = args[2].toInt32(); // 比较的字节数
// 确保指针有效
if (ptr1 && !ptr1.isNull() && ptr2 && !ptr2.isNull()) {
var str1 =Memory.readCString(ptr1)
var str2 =Memory.readCString(ptr2)
// 输出比较的内容
//console.log('Memory 1: ' + hexdump(ptr1, { length: numBytes, ansi: true }));
//console.log('Memory 2: ' + hexdump(ptr2, { length: numBytes, ansi: true }));
//console.log('Number of bytes: ' + numBytes + '\n'); // 比较的字节数
if (str1 && str1.includes(target)) {
console.log('memcmp called from:\n' +
Thread.backtrace(this.context, Backtracer.ACCURATE)
.map(DebugSymbol.fromAddress).join('\n')); // 打印调用栈
console.log('Memory 1: ' + str1); // 第一个内存块的内容
}
if (str2 && str2.includes(target)) {
console.log('memcmp called from:\n' +
Thread.backtrace(this.context, Backtracer.ACCURATE)
.map(DebugSymbol.fromAddress).join('\n')); // 打印调用栈
console.log('Memory 2: ' + str2); // 第二个内存块的内容
}
}
},
onLeave: function(retval) {
//console.log('memcmp returned: ' + retval);
}
});
}
function hook_strlen(){
var libc = Module.findBaseAddress('libc.so');
var strlenAddress = Module.findExportByName('libc.so', 'strlen');
if (!strlenAddress) {
console.log('strlen not found');
return;
}
Interceptor.attach(strlenAddress, {
onEnter: function(args) {
var strPtr = args[0]; // 获取指向字符串的指针
// 确保指针有效
if (strPtr && !strPtr.isNull()) {
var str = Memory.readCString(strPtr); // 读取 C 字符串
// 检查是否包含目标字符串
if (str.includes(target)) {
console.log('memcpy called from:\n' +
Thread.backtrace(this.context, Backtracer.ACCURATE)
.map(DebugSymbol.fromAddress).join('\n')); // 打印调用栈
console.log('Target string found in input========>>>>' + str);
}
}
},
onLeave: function(retval) {
//console.log('strlen returned: ' + retval.toInt32()); // 打印返回的字符串长度
}
});
}
function hook_memmove(){
var libc = Module.findBaseAddress('libc.so');
var memmoveAddress = Module.findExportByName('libc.so', 'memmove');
if (!memmoveAddress) {
console.log('memmove not found');
return;
}
Interceptor.attach(memmoveAddress, {
onEnter: function(args) {
var destPtr = args[0]; // 目标地址
var srcPtr = args[1]; // 源地址
var numBytes = args[2].toInt32(); // 拷贝的字节数
// 确保指针有效
if (srcPtr && !srcPtr.isNull() && destPtr && !destPtr.isNull()) {
var srcString = Memory.readCString(srcPtr);
// 检查是否包含目标字符串
if (srcString.includes(target)) {
console.log('memmove called from:\n' +
Thread.backtrace(this.context, Backtracer.ACCURATE)
.map(DebugSymbol.fromAddress).join('\n')); // 打印调用栈
console.log('Target string found in src======>>>>>' + srcString);
}
}
},
onLeave: function(retval) {
//console.log('memmove returned: ' + retval); // 打印返回值
}
});
}
function hook_strstr() {
var libc = Module.findBaseAddress('libc.so');
var strstrAddress = Module.findExportByName('libc.so', 'strstr');
if (!strstrAddress) {
console.log('strstr not found');
return;
}
Interceptor.attach(strstrAddress, {
onEnter: function(args) {
var haystackPtr = args[0]; // 搜索的目标字符串
var needlePtr = args[1]; // 要查找的子字符串
// 确保指针有效
if (haystackPtr && !haystackPtr.isNull() && needlePtr && !needlePtr.isNull()) {
var haystackString = Memory.readCString(haystackPtr); // 读取目标字符串
var needleString = Memory.readCString(needlePtr); // 读取要查找的子字符串
// 检查是否包含目标字符串
if (haystackString.includes(target) || needleString.includes(target)) {
console.log('strstr called from:\n' +
Thread.backtrace(this.context, Backtracer.ACCURATE)
.map(DebugSymbol.fromAddress).join('\n')); // 打印调用栈
console.log('Target string found in haystack=======>>>>>' + haystackString);
console.log('Target string found in needle======>>>>>' + needleString);
}
}
},
onLeave: function(retval) {
}
});
}
function hook_strncpy() {
var libc = Module.findBaseAddress('libc.so'); // 获取 libc.so 的基本地址
var strncpyAddress = Module.findExportByName('libc.so', 'strncpy'); // 找到 strncpy 函数的地址
if (!strncpyAddress) {
console.log('strncpy not found');
return;
}
Interceptor.attach(strncpyAddress, {
onEnter: function(args) {
var destPtr = args[0]; // 目标地址
var srcPtr = args[1]; // 源地址
var numBytes = args[2].toInt32(); // 要拷贝的字节数
// 确保指针有效
if (srcPtr && !srcPtr.isNull() && destPtr && !destPtr.isNull()) {
var srcString = Memory.readCString(srcPtr); // 读取源字符串
// 检查是否包含目标字符串
if (srcString.includes(target)) {
// 输出调用信息
console.log('strncpy called from:\n' +
Thread.backtrace(this.context, Backtracer.ACCURATE)
.map(DebugSymbol.fromAddress).join('\n')); // 打印调用栈
console.log('Target string found in src======>>>>' + srcString);
}
}
},
onLeave: function(retval) {
//console.log('strncpy returned: ' + retval); // 打印返回值
}
});
}
function hook_strncmp() {
var libc = Module.findBaseAddress('libc.so'); // 获取 libc.so 的基本地址
var strncmpAddress = Module.findExportByName('libc.so', 'strncmp'); // 找到 strncmp 函数的地址
if (!strncmpAddress) {
console.log('strncmp not found');
return;
}
Interceptor.attach(strncmpAddress, {
onEnter: function(args) {
var str1Ptr = args[0]; // 第一个字符串的指针
var str2Ptr = args[1]; // 第二个字符串的指针
var numChars = args[2].toInt32(); // 要比较的字符数
// 确保指针有效
if (str1Ptr && !str1Ptr.isNull() && str2Ptr && !str2Ptr.isNull()) {
var str1 = Memory.readCString(str1Ptr); // 读取第一个字符串
var str2 = Memory.readCString(str2Ptr); // 读取第二个字符串
// 检查是否包含目标字符串
if (str1.includes(target)|| str2.includes(target)) {
console.log('strncmp called from:\n' +
Thread.backtrace(this.context, Backtracer.ACCURATE)
.map(DebugSymbol.fromAddress).join('\n')); // 打印调用栈
console.log('Target string found in str1======>>>>' + str1);
console.log('Target string found in str2======>>>>' + str2);
}
}
},
onLeave: function(retval) {
//console.log('strncmp returned: ' + retval.toInt32()); // 打印返回值
}
});
}
function hook_strncat() {
var libc = Module.findBaseAddress('libc.so'); // 获取 libc.so 的基本地址
var strncatAddress = Module.findExportByName('libc.so', 'strncat'); // 找到 strncat 函数的地址
if (!strncatAddress) {
console.log('strncat not found');
return;
}
Interceptor.attach(strncatAddress, {
onEnter: function(args) {
var destPtr = args[0]; // 目标字符串的指针
var srcPtr = args[1]; // 源字符串的指针
var numBytes = args[2].toInt32(); // 要追加的字节数
// 确保指针有效
if (destPtr && !destPtr.isNull() && srcPtr && !srcPtr.isNull()) {
var destString = Memory.readCString(destPtr); // 读取目标字符串
var srcString = Memory.readCString(srcPtr); // 读取源字符串
// 检查源字符串中是否包含目标字符串
if (srcString.includes(target) || destString.includes(target)) {
console.log('strncat called from:\n' +
Thread.backtrace(this.context, Backtracer.ACCURATE)
.map(DebugSymbol.fromAddress).join('\n')); // 打印调用栈
console.log('Target string found in src======>>>>' + srcString);
console.log('Target string found in dest======>>>>>' + destString);
}
}
},
onLeave: function(retval) {
//console.log('strncat returned: ' + retval); // 打印返回值
}
});
}
hook_strncat()

浙公网安备 33010602011771号