字符串搜索一把梭,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()

 

posted @ 2024-11-12 21:59  GGBomb  阅读(199)  评论(0)    收藏  举报