✦₊ 点击蓝字,关注我们 🌷
日期:2025年3月15日
作者:Zero
介绍:几个Frida在Windows下的使用技巧。
1、前言
在软件安全研究与逆向工程领域,Frida
凭借其革命性的动态插桩技术,已成为穿透程序黑盒的“数字X光机”。这款开源工具通过JavaScript
脚本实时注入进程,让研究人员如同拥有“时间暂停”能力般观察程序运行细节——从函数调用轨迹到内存数据流转,所有隐秘行为尽收眼底。
相较于传统静态分析工具,Frida
的跨平台特性使其能无缝衔接Android
、iOS
、Windows
等多系统环境。
以下是Frida
在Windows
下进行逆向分析的一些技巧及具体脚本示例。
2、技巧备忘录
2.1 Hook 程序函数参数及返回值
使用Frida
的Interceptor.attach
方法来Hook
目标程序中的特定函数。
Interceptor.attach(ptr("0xxxxxxxxx"), {
onEnter: function(args) {
console.log("Function called with arguments:");
for (var i = 0; i < 5; i++) { // 参数数量
if (args[i] !== undefined) {
console.log("arg[" + i + "]: " + args[i].toInt32());
}
}
},
onLeave: function(retval) {
console.log("Function return value: " + retval.toInt32());
}
});
2.2 枚举模块及其导入导出函数
使用Frida
枚举目标进程已加载的模块。
var modules = Process.enumerateModules();
for (var i = 0; i < modules.length; i++) {
var mod = modules[i];
console.log("Name: " + mod.name);
console.log("Base Address: " + mod.base);
console.log("Size: " + mod.size);
console.log("Path: " + mod.path);
console.log("-------------------------------");
}
枚举特定模块的导出函数。
var moduleName = "kernel32.dll";
var module = Process.findModuleByName(moduleName);
if (module) {
var exports = Module.enumerateExports(moduleName);
for (var i = 0; i < exports.length; i++) {
var exp = exports[i];
console.log("Name: " + exp.name);
console.log("Address: " + exp.address);
console.log("Type: " + exp.type);
console.log("-------------------------------");
}
} else {
console.log("Module not found: " + moduleName);
}
枚举特定模块的导入函数。
var moduleName = "kernel32.dll";
var module = Process.findModuleByName(moduleName);
if (module) {
var imports = Module.enumerateImports(moduleName);
for (var i = 0; i < imports.length; i++) {
var imp = imports[i];
console.log("Name: " + imp.name);
console.log("Address: " + imp.address);
console.log("Module: " + imp.module);
console.log("Type: " + imp.type);
console.log("-------------------------------");
}
} else {
console.log("Module not found: " + moduleName);
}
2.3 Hook 系统 API
Frida
可以Hook Windows
的系统API
,如文件操作、网络通信等。以下是一个Hook WriteFile
函数的示例:
Interceptor.attach(Module.findExportByName("kernel32.dll", "WriteFile"), {
onEnter: function(args) {
console.log("WriteFile called");
var hFile = args[0];
var lpBuffer = args[1];
var nNumberOfBytesToWrite = args[2];
var lpNumberOfBytesWritten = args[3];
var lpOverlapped = args[4];
console.log("hFile: " + hFile + ", Buffer: " + lpBuffer + ", BytesToWrite: " + nNumberOfBytesToWrite);
},
onLeave: function(retval) {
console.log("WriteFile returned");
}
});
2.4 主动调用系统 API
Frida
可以Hook Windows
的系统API
,如文件操作、网络通信等。以下是一个Hook WriteFile
函数的示例:
var user32 = new NativeFunction(Module.findExportByName("user32.dll", "MessageBoxW"), 'int', ['pointer', 'pointer', 'pointer', 'int']);
var hInstance = null;
var lpText = Memory.allocUtf16String("Hello from Frida!");
var lpCaption = Memory.allocUtf16String("Frida MessageBox");
var uType = 0x00000000; // MB_OK
user32(hInstance, lpText, lpCaption, uType);
2.5 修改内存数据
利用Frida
的内存操作功能,可以在运行时修改目标程序的内存数据。以下是一个修改内存中字符串的示例:
var address = ...; // 目标内存地址
var newString = "New string";
Memory.writeUtf16String(address, newString);
2.6 动态调试与断点设置
Frida
支持动态设置断点,可以在特定函数调用时暂停程序执行。以下是一个设置断点的示例:
Interceptor.attach(Module.findExportByName("kernel32.dll", "LoadLibraryW"), {
onEnter: function(args) {
console.log("LoadLibraryW called");
var lpLibFileName = Memory.readUtf16String(args[0]);
console.log("Lib name: " + lpLibFileName);
DebugSymbol.loadModule("kernel32.dll");
var funcAddr = DebugSymbol.getFunctionByName("kernel32.dll", "LoadLibraryW");
var breakpoint = new Breakpoint(funcAddr);
breakpoint.onHit = function() {
console.log("Breakpoint hit at LoadLibraryW");
};
}
});
2.7 观察恶意软件行为
使用Frida
拦截恶意软件的关键函数调用,以观察其行为。例如,拦截LoadLibraryW
和GetProcAddress
函数。
Interceptor.attach(Module.findExportByName("kernel32.dll", "LoadLibraryW"), {
onEnter: function(args) {
console.log("LoadLibraryW called");
var lpLibFileName = Memory.readUtf16String(args[0]);
console.log("Lib name: " + lpLibFileName);
}
});
Interceptor.attach(Module.findExportByName("kernel32.dll", "GetProcAddress"), {
onEnter: function(args) {
console.log("GetProcAddress called");
var hModule = args[0];
var lpProcName = args[1];
console.log("Module: " + hModule + ", Proc name: " + lpProcName);
}
});
2.8 Frida-RPC 机制
Frida
提供了RPC
机制,可以通过Python
脚本调用Frida
中的JavaScript
函数。
rpc.exports = {
get_message: function() {
return "Hello World!";
}
};
在Python
脚本中调用:
import frida
device = frida.get_local_device()
process = device.attach("target_process")
script = process.create_script(jscode)
script.load()
result = script.exports.get_message()
print(result)
3、结语
水文一篇,感谢前辈们的付出让这个世界变得丰富多彩,同时也感谢您能看到此处~~~ 关注我们了解更多趣事,我们下期见!
免责声明:本文仅供安全研究与讨论之用,严禁用于非法用途,违者后果自负。
点此亲启
ABOUT US
宸极实验室隶属山东九州信泰信息科技股份有限公司,致力于网络安全对抗技术研究,是山东省发改委认定的“网络安全对抗关键技术山东省工程研究中心”。团队成员专注于 Web 安全、移动安全、红蓝对抗等领域,善于利用黑客视角发现和解决网络安全问题。
团队自成立以来,圆满完成了多次国家级、省部级重要网络安全保障和攻防演习活动,并积极参加各类网络安全竞赛,屡获殊荣。
对信息安全感兴趣的小伙伴欢迎加入宸极实验室,关注公众号,回复『招聘』,获取联系方式。
原文始发于微信公众号(黑白之道):『CTF』Frida-Windows场景使用技巧备忘录
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论