提交 cb07d245 编写于 作者: K Knine

frida api封装

上级 f68d31d8
function logH1(title: String) {
console.log(`
=================================================================
================================ ${title}
=================================================================
`)
}
function logH2(title: String) {
console.log(`
================================ ${title}
`)
}
export { logH1, logH2 } // 导出函数
import { logH1, logH2 } from "./common";
import { testSnippets } from "./snippets";
// Runtime information
function getRuntimeInfo() {
logH1("Runtime information")
// Frida
logH2("Frida")
console.log('Frida.version:', Frida.version)
console.log('Frida.heapSize:', Frida.heapSize)
// Script (QJS or V8)
logH2("Script")
console.log('Script.runtime:', Script.runtime)
}
// Process
function show_process() {
logH1("Process")
console.log("Process.id:\t\t", Process.id);
console.log("Process.getCurrentThreadId():\t", Process.getCurrentThreadId());
console.log("Process.arch:\t\t", Process.arch);
console.log("Process.platform:\t", Process.platform);
console.log("Process.pageSize:\t", Process.pageSize);
console.log("Process.pointerSize:\t", Process.pointerSize);
console.log("Process.codeSigningPolicy:\t", Process.codeSigningPolicy);
// 下面三个接口, frida 15.0.18 还不支持;16.0.8 版本测试通过
console.log("Process.getCurrentDir():\t", Process.getCurrentDir());
console.log("Process.getHomeDir():\t", Process.getHomeDir());
console.log("Process.getTmpDir():\t", Process.getTmpDir());
logH2("Process.enumerateThreads")
let threads = Process.enumerateThreads();
for (const iterator of threads) {
console.log(JSON.stringify(iterator));
}
logH2("Process.enumerateModules")
let modules = Process.enumerateModules();
for (const iterator of modules) {
console.log(JSON.stringify(iterator));
}
logH2("Process.enumerateRanges")
let ranges = Process.enumerateRanges("rwx");
for (const iterator of ranges) {
console.log(JSON.stringify(iterator));
}
// let mallocRanges = Process.enumerateMallocRanges();
// for (const iterator of mallocRanges) {
// console.log(JSON.stringify(iterator));
// }
}
// Thread
function show_thread() {
logH1("Thread")
// Thread.backtrace 有机会以后再写吧
// Thread.sleep
console.log("Thread.sleep(1000) start...");
// 单位:秒、seconds
Thread.sleep(1)
console.log("Thread.sleep(1000) finish...");
}
// Module
function show_module() {
logH1("Module")
let module = Process.getModuleByName("winmine.exe");
// let module = Process.getModuleByName("user32.dll");
// module = Process.getModuleByName("Kernel32.dll");
console.log("module", JSON.stringify(module, null, 4));
logH2("Imports:");
for (const iterator of module.enumerateImports()) {
console.log(JSON.stringify(iterator));
}
logH2("Exports:");
for (const iterator of module.enumerateExports()) {
console.log(JSON.stringify(iterator));
}
logH2("Symbols:");
for (const iterator of module.enumerateSymbols()) {
console.log(JSON.stringify(iterator));
}
// enumerateRanges
logH2("Ranges:");
for (const iterator of module.enumerateRanges("r--")) {
console.log(JSON.stringify(iterator));
}
// {"type":"function","name":"lstrlenW","address":"0x7630e0b0"}
let p = module.findExportByName("lstrlenW");
console.log(p);
let p1 = Module.load("DBGHELP.DLL");
console.log(JSON.stringify(p1));
logH2("Exports:");
for (const iterator of p1.enumerateExports()) {
console.log(JSON.stringify(iterator));
}
logH2("Imports:");
for (const iterator of p1.enumerateImports()) {
console.log(JSON.stringify(iterator));
}
}
// Memory
function show_memory() {
logH1("Memory")
// console.log(JSON.stringify(Memory));
let module = Process.getModuleByName("winmine.exe");
let p = ptr(0x00210604);
let pattern = p.toMatchPattern();
console.log("pattern", pattern);
// Memory.scan(module.base, module.size, pattern, {
Memory.scan(module.base, module.size, "04 ?? ?1 ?0", {
onMatch: (address, size) => {
console.log("onMatch", size, address, address.sub(module.base));
},
onError: (reason) => {
console.log(reason);
},
onComplete: () => {
console.log("Scan Complete!");
}
});
// let matches = Memory.scanSync(module.base, module.size, pattern);
let matches = Memory.scanSync(module.base, module.size, "04 ?? ?1 ?0");
for (const iterator of matches) {
console.log(JSON.stringify(iterator));
}
let m1 = Memory.alloc(Process.pageSize);
console.log("protect", JSON.stringify(Process.getRangeByAddress(m1)));
Memory.protect(m1, Process.pageSize, "r-x");
console.log("protect", JSON.stringify(Process.getRangeByAddress(m1)));
let lpText = Memory.allocUtf16String("This is a string!");
let lpCaption = Memory.allocUtf16String("Caption");
// WinApi.MessageBox(p, lpText, lpCaption, 0x00000001);
let m2 = Memory.alloc(Process.pageSize);
console.log("m2", m2);
let address = Module.getExportByName("User32.dll", "MessageBoxW");
Memory.patchCode(m2, Process.pageSize, (code) => {
// console.log("code", code);
let asm = new X86Writer(code);
asm.putPushU32(0x00000001);
asm.putPushU32(lpCaption.toUInt32());
asm.putPushU32(lpText.toUInt32());
// asm.putPushU32(p.toUInt32());
asm.putPushU32(0);
asm.putCallAddress(address);
asm.putRet();
asm.flush();
});
let func = new NativeFunction(m2, "void", []);
func();
}
// Interceptor
function show_interceptor() {
// DispatchMessageW
let address = Module.getExportByName("User32.dll", "DispatchMessageW");
// console.log(JSON.stringify(Interceptor));
Interceptor.attach(address, {
onEnter(this, args) {
// console.log(this.context, this.depth, this.errno, this.lastError, this.returnAddress, this.threadId);
console.log(JSON.stringify(this.context));
// typedef struct tagMSG {
// HWND hwnd;
// UINT message;
// WPARAM wParam;
// LPARAM lParam;
// DWORD time;
// POINT pt;
// DWORD lPrivate;
// } MSG, *PMSG, *NPMSG, *LPMSG;
console.log('args[0]: ', args[0]);
console.log(args[1]);
console.log(args[2]);
console.log(args[3]);
console.log(args[4]);
console.log('args[5]: ', args[5]);
let msg = args[0];
console.log("hwnd", msg.readPointer());
console.log("message", msg.add(4).readPointer());
console.log("wParam", msg.add(8).readPointer());
console.log("lParam", msg.add(12).readPointer());
console.log("pt", msg.add(20).readPointer());
console.log("lPrivate", msg.add(24).readPointer());
},
onLeave(this, retval) {
console.log(JSON.stringify(this.context));
console.log(retval);
},
});
}
function main() {
getRuntimeInfo()
show_process()
show_thread()
show_module()
// show_memory()
// show_interceptor()
logH1("Snippets")
testSnippets()
}
main()
// Converts an integer (unicode value) to a char
function itoa(i: number)
{
return String.fromCharCode(i);
}
// Converts a char into to an integer (unicode value)
function atoi(a: { charCodeAt: () => any; })
{
return a.charCodeAt();
}
// i to hex
function itohex(i: { toString: (arg0: number) => any; })
{
var s = i.toString(16);
s = ('00000000' + s).slice(-8);
return [s.slice(6, 8), s.slice(4, 6), s.slice(2, 4), s.slice(0, 2)].join(' ');
}
// itohex(0x1122334);
function str2hex(s: string | any[]) { // buffer is an ArrayBuffer
// for each element, we want to get its two-digit hexadecimal representation
const hexParts = [];
for(let i = 0; i < s.length; i++) {
// convert value to hexadecimal
const hex = atoi(s[i]).toString(16);
// pad with zeros to length 2
const paddedHex = ('00' + hex).slice(-2);
// push to array
hexParts.push(paddedHex);
}
// join all the hex values of the elements into a single string
return hexParts.join(' ');
}
// str2hex('ssssk')
function buf2hex(buffer: Iterable<number>) { // buffer is an ArrayBuffer
// create a byte array (Uint8Array) that we can use to read the array buffer
const byteArray = new Uint8Array(buffer);
// for each element, we want to get its two-digit hexadecimal representation
const hexParts = [];
for(let i = 0; i < byteArray.length; i++) {
// convert value to hexadecimal
const hex = byteArray[i].toString(16);
// pad with zeros to length 2
const paddedHex = ('00' + hex).slice(-2);
// push to array
hexParts.push(paddedHex);
}
// join all the hex values of the elements into a single string
return hexParts.join(' ');
}
// 根据类名获取虚表地址
function GetVTableByClassName(dll_name: string, func: string) {
var module = Module.load(dll_name);
var s = ".?AV" + func + "@@";
var results = Memory.scanSync(module.base, module.size, str2hex(s));
// class GxxLogin::LoginAccountPage `RTTI Type Descriptor'
// var nRTTITypeDescriptor = eval(results[0].address)-8;
var nRTTITypeDescriptor = results[0].address-0x08;
// MyLogD(results[0].address, itohex(nRTTITypeDescriptor));
results = Memory.scanSync(module.base, module.size, itohex(nRTTITypeDescriptor));
// MyLogD(JSON.stringify(results));
// RTTI Complete Object Locator
var nRTTI_COL = eval(results[0].address) - 0x0c;
// MyLogD(nRTTI_COL, itohex(nRTTI_COL));
results = Memory.scanSync(module.base, module.size, itohex(nRTTI_COL));
// MyLogD(JSON.stringify(results), eval(results[0].address), eval(results[0].address)-0+0x04);
return eval(results[0].address)-0+0x04;
}
// MyLogD(GetVTable('LoginAccountPage@GxxLogin'));
// 通过对象获取虚表
// .?AVContextualErrorEdit@Phoenix@@ 战网的 accountNameEdit 、 passwordEdit 都是这个类实现的
// .data:1164F34C ; public class Phoenix::ContextualErrorEdit /* mdisp:0 */ :
// .data:1164F34C ; public class QWidget /* mdisp:0 */ :
// .data:1164F34C ; public class QObject /* mdisp:0 */,
// .data:1164F34C ; public class QPaintDevice /* mdisp:8 */
// .data:1164F34C ; class Phoenix::ContextualErrorEdit `RTTI Type Descriptor'
// .data:1164F34C ??_R0?AVContextualErrorEdit@Phoenix@@@8 dd offset ??_7type_info@@6B@
function GetVTableNameByObj(obj: string | number | NativePointer) {
// TODO:
var pCol = ptr(obj).readPointer().sub(4).readPointer();
var pTypeDescriptor = pCol.add(4*3).readPointer();
return pTypeDescriptor.add(4*2).readCString()
}
console.log('GetVTableNameByObj =', GetVTableNameByObj(ptr('0x821be68')));
// demo() {
// let address = Module.getExportByName("User32.dll", "MessageBoxW");
// let m2 = Memory.alloc(Process.pageSize);
// let asm = new X86Writer(m2);
// asm.putPushU32(0x00000001);
// asm.putPushU32(2);
// asm.putPushU32(3);
// asm.putPushU32(4);
// asm.putCallAddress(address);
// asm.putRet();
// asm.putPushReg("eax");
// asm.flush();
// // this.show_asm(m2);
// this.show_asm(ptr(0x01003E21));
// }
function show_asm(start: NativePointer, length: number = 10) {
for (let index = 0; index < length; index++) {
let inst = Instruction.parse(start);
// console.log(JSON.stringify(inst));
let byteArray = start.readByteArray(inst.size);
let byteCode = Array.prototype.slice.call(new Uint8Array(byteArray!));
let mCode = byteCode.map(x => x.toString(16).padStart(2, "0")).join(" ").toUpperCase();
console.log(inst.address.toString().toUpperCase().replace("0X", "0x"), mCode.padEnd(14, " "), "\t", inst.toString().toUpperCase().replace("0X", "0x"));
start = inst.next;
if (start.readU32() == 0) break;
}
}
function testSnippets() {
let address = Module.getExportByName("User32.dll", "MessageBoxW");
show_asm(address);
}
export { testSnippets };
\ No newline at end of file
// using fnQApplication_topLevelWidgets = QListData * (_cdecl*)(void*);
var fnQApplication_topLevelWidgets = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?topLevelWidgets@QApplication@@SA?AV?$QList@PAVQWidget@@@@XZ'),
'pointer',
['pointer'],
'mscdecl'
);
// ?x@QWidget@@QBEHXZ
// 符号(已解码)=public: int __thiscall QWidget::x(void)const
var fnQWidget_x = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?x@QWidget@@QBEHXZ'),
'int',
['pointer'],
'thiscall'
);
// ?y@QWidget@@QBEHXZ
// 符号(已解码)=public: int __thiscall QWidget::y(void)const
var fnQWidget_y = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?y@QWidget@@QBEHXZ'),
'int',
['pointer'],
'thiscall'
);
// ?mapFromGlobal@QWidget@@QBE?AVQPoint@@ABV2@@Z
// 符号(已解码)=public: class QPoint __thiscall QWidget::mapFromGlobal(class QPoint const &)const
var fnQWidget_mapFromGlobal = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?mapFromGlobal@QWidget@@QBE?AVQPoint@@ABV2@@Z'),
'pointer',
['pointer', 'pointer', 'pointer'],
'thiscall'
);
// ?mapToGlobal@QWidget@@QBE?AVQPoint@@ABV2@@Z
// 符号(已解码)=public: class QPoint __thiscall QWidget::mapToGlobal(class QPoint const &)const
var fnQWidget_mapToGlobal = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?mapToGlobal@QWidget@@QBE?AVQPoint@@ABV2@@Z'),
'pointer',
['pointer', 'pointer', 'pointer'],
'thiscall'
);
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 获取相对于顶层窗口的坐标
function ez_fnQWidget_pos(obj) {
var qpoint_param = Memory.alloc(8);
try {
var ret = fnQWidget_pos(obj, qpoint_param);
var x = ret.add(0).readS32();
var y = ret.add(4).readS32();
// MyLogD('\t\t ez_fnQWidget_pos', qpoint_param.readU64().toString(16), ',x=', x, ',y=', y);
} catch (error) {
MyLogE('【catch】 ez_fnQWidget_pos', error);
}
return ret;
}
function ez_fnQWidget_mapFromGlobal(obj, point) {
var ret;
try {
var ret2 = Memory.alloc(8);
ret = fnQWidget_mapFromGlobal(obj, ret2, point);
var x = ret.add(0).readS32();
var y = ret.add(4).readS32();
MyLogD('\t\t ez_fnQWidget_mapFromGlobal', ret2.readU64().toString(16), ',x=', x, ',y=', y);
} catch (error) {
MyLogE('【catch】 ez_fnQWidget_mapFromGlobal', error, ret);
}
return ret;
}
function ez_fnQWidget_mapFromGlobal_x(obj) {
try {
var pos = ez_fnQWidget_pos(obj);
var pos2 = ez_fnQWidget_mapFromGlobal(obj, pos);
if (pos2) {
return pos2.readU32();
}
} catch (error) {
}
return -1;
}
function ez_fnQWidget_mapFromGlobal_y(obj) {
try {
var pos = ez_fnQWidget_pos(obj);
var pos2 = ez_fnQWidget_mapFromGlobal(obj, pos);
if (pos2) {
return pos2.add(4).readU32();
}
} catch (error) {
}
return -2;
}
function ez_fnQWidget_mapFromGlobal_xy(obj) {
try {
var pos = ez_fnQWidget_pos(obj);
// MyLogD('【 111 】 ez_fnQWidget_mapFromGlobal_xy', pos);
if(pos) {
var pos2 = ez_fnQWidget_mapFromGlobal(obj, pos);
// MyLogD('【 222 】 ez_fnQWidget_mapFromGlobal_xy', pos2);
if (pos2) {
// MyLogD('【 333 】 ez_fnQWidget_mapFromGlobal_xy', pos2);
return `${pos2.readS32()},${pos2.add(4).readS32()}`;
}
}
} catch (error) {
MyLogE('【catch】 ez_fnQWidget_mapFromGlobal_xy', error);
}
return `-1,-2`;
}
function ez_fnQWidget_mapToGlobal(obj, point) {
var ret2 = Memory.alloc(8);
try {
var ret = fnQWidget_mapToGlobal(obj, point, ret2);
// var x = ret.add(0).readS32();
// var y = ret.add(4).readS32();
// MyLogD('\t\t ez_fnQWidget_mapToGlobal', ret2.readU64().toString(16), ',x=', x, ',y=', y);
} catch (error) {
MyLogE('【catch】 ez_fnQWidget_mapToGlobal', error);
}
return ret2;
}
function ez_fnQWidget_mapToGlobal_xy(obj) {
try {
var pos = ez_fnQWidget_pos(obj);
// MyLogD('【 111 】 ez_fnQWidget_mapToGlobal_xy', pos);
if(pos) {
var pos2 = ez_fnQWidget_mapToGlobal(obj, pos);
// MyLogD('【 222 】 ez_fnQWidget_mapToGlobal_xy', pos2);
if (pos2) {
// MyLogD('【 333 】 ez_fnQWidget_mapToGlobal_xy', pos2);
return `${pos2.readS32()},${pos2.add(4).readS32()}`;
}
}
} catch (error) {
MyLogE('【catch】 ez_fnQWidget_mapToGlobal_xy', error);
}
return `-1,-2`;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ?isVisible@QWidget@@QBE_NXZ
// public: bool __thiscall QWidget::isVisible(void)const
var fnQWidget_isVisible = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?isVisible@QWidget@@QBE_NXZ'),
'bool',
['pointer'],
'thiscall'
);
// public: class QPoint __thiscall QWidget::pos(void)const
var fnQWidget_pos = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?pos@QWidget@@QBE?AVQPoint@@XZ'),
'pointer',
['pointer', 'pointer'],
'thiscall'
);
// public: class QSize __thiscall QWidget::size(void)const
var fnQWidget_size = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?size@QWidget@@QBE?AVQSize@@XZ'),
'pointer',
['pointer', 'pointer'],
'thiscall'
);
// public: void __thiscall QLineEdit::setText(class QString const &)
var fnQLineEdit_setText = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?setText@QLineEdit@@QAEXABVQString@@@Z'),
'void',
['pointer', 'pointer'],
'thiscall'
);
// public: void __thiscall QLineEdit::textChanged(class QString const &)
var fnQLineEdit_textChanged = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?textChanged@QLineEdit@@QAEXABVQString@@@Z'),
'void',
['pointer', 'pointer'],
'thiscall'
);
// public: void __thiscall QCheckBox::setCheckState(enum Qt::CheckState)
var fnQCheckBox_setCheckState = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?setCheckState@QCheckBox@@QAEXW4CheckState@Qt@@@Z'),
'void',
['pointer', 'int'],
'thiscall'
);
// public: void __thiscall QAbstractButton::setChecked(bool)
var fnQAbstractButton_setChecked = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?setChecked@QAbstractButton@@QAEX_N@Z'),
'void',
['pointer', 'bool'],
'thiscall'
);
// 符号(已解码)=public: void __thiscall QAbstractButton::click(void)
var fnQAbstractButton_click = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?click@QAbstractButton@@QAEXXZ'),
'void',
['pointer'],
'thiscall'
);
// fnQAbstractButton_click(ptr(my_read_u32(ptr(0xee7178).add(0x70))))
// 符号=?text@QAbstractButton@@QBE?AVQString@@XZ
// 符号(已解码)=public: class QString __thiscall QAbstractButton::text(void)const
var fnQAbstractButton_text = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?text@QAbstractButton@@QBE?AVQString@@XZ'),
'pointer',
['pointer', 'pointer'],
'thiscall'
);
function ez_fnQAbstractButton_text(obj) {
var s = ez_fnQString_fromUtf8('')
fnQAbstractButton_text(obj, s);
return QString2JsString(s)
}
// public: class QString __thiscall QLabel::text(void)const
var fnQLabel_text = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?text@QLabel@@QBE?AVQString@@XZ'),
'void',
['pointer','pointer'],
'thiscall'
);
function ez_fnQLabel_text(obj) {
// var retQString = Memory.alloc(Process.pointerSize);
var retQString = ez_fnQString_fromUtf8('');
fnQLabel_text(obj, ptr(retQString));
MyLogD(retQString);
return my_read_u32_to_obj(retQString).add(0x10).readUtf16String();
}
function QString2JsString(qstr) {
return ptr('0x'+qstr.readU64().toString(16)).add(0x10).readUtf16String();
}
//////////////////////////////////////////////////////////////////////////////////////////
// Qt5Core.dll
//////////////////////////////////////////////////////////////////////////////////////////
/*
地址=00007FFF68C67E60
类型=导出
序号=3828
符号=?fromUtf8@QString@@SA?AV1@PEBDH@Z
符号(已解码)=public: static class QString __cdecl QString::fromUtf8(char const * __ptr64,int)
地址=00007FFF68C64730
类型=导出
序号=1121
符号=??4QString@@QEAAAEAV0@PEBD@Z
符号(已解码)=public: class QString & __ptr64 __cdecl QString::operator=(char const * __ptr64) __ptr64
地址=00007FFF68E65690
类型=导出
序号=5223
符号=?objectName@QObject@@QEBA?AVQString@@XZ
符号(已解码)=public: class QString __cdecl QObject::objectName(void)const __ptr64
*/
// console.log('fnQString_fromUtf8 = ', Module.findExportByName('Qt5Core.dll', '?fromUtf8@QString@@SA?AV1@PBDH@Z'));
// 返回值大于4字节,当做第一个参数传递进去了!!!
// public: static class QString __cdecl QString::fromUtf8(char const *,int)
var fnQString_fromUtf8 = new NativeFunction(
Module.findExportByName('Qt5Core.dll', '?fromUtf8@QString@@SA?AV1@PEBDH@Z'),
'void',
['pointer','pointer', 'int'],
'win64'
);
function ez_fnQString_fromUtf8(jsStr){
var retQString = Memory.alloc(Process.pointerSize);
var cStrPointer = Memory.allocUtf8String(jsStr);
fnQString_fromUtf8(retQString, cStrPointer, -1);
return retQString;
}
var fn_QString_operator_asign_char = new NativeFunction(
Module.findExportByName('Qt5Core.dll', '??4QString@@QEAAAEAV0@PEBD@Z'),
'void',
['pointer','pointer'],
'win64'
);
function ez_fn_QString_operator_asign_char(obj, jsStr) {
var cStrPointer = Memory.allocUtf8String(jsStr);
fn_QString_operator_asign_char(obj, cStrPointer);
}
// using fnQObject_objectName = void* (__thiscall*)(void* pthis, void* qstr);
var fnQObject_objectName = new NativeFunction(
Module.findExportByName('Qt5Core.dll', '?objectName@QObject@@QEBA?AVQString@@XZ'),
'pointer',
['pointer', 'pointer'],
'win64'
);
function ez_fnQObject_objectName(obj) {
var p = Memory.alloc(8);
p.writeU32(0);
fnQObject_objectName(obj, p);
console.log('ez_fnQObject_objectName >>> ', p.toString(16))
console.log(hexdump(p, {
offset: 0,
length: 0x80,
header: true,
ansi: false
}));
return p;
}
//////////////////////////////////////////////////////////////////////////////////////////
// Qt5Widgets - QWidget
//////////////////////////////////////////////////////////////////////////////////////////
/*
地址=00007FFF60F7AEC0
类型=导出
序号=8298
符号=?topLevelWidgets@QApplication@@SA?AV?$QList@PEAVQWidget@@@@XZ
符号(已解码)=public: static class QList<class QWidget * __ptr64> __cdecl QApplication::topLevelWidgets(void)
地址=00007FFF60FB2670
类型=导出
序号=9029
符号=?x@QWidget@@QEBAHXZ
符号(已解码)=public: int __cdecl QWidget::x(void)const __ptr64
地址=00007FFF60FB26E0
类型=导出
序号=9037
符号=?y@QWidget@@QEBAHXZ
符号(已解码)=public: int __cdecl QWidget::y(void)const __ptr64
地址=00007FFF60FA0B80
类型=导出
序号=4220
符号=?mapFromGlobal@QWidget@@QEBA?AVQPoint@@AEBV2@@Z
符号(已解码)=public: class QPoint __cdecl QWidget::mapFromGlobal(class QPoint const & __ptr64)const __ptr64
地址=00007FFF60FA0CF0
类型=导出
序号=4264
符号=?mapToGlobal@QWidget@@QEBA?AVQPoint@@AEBV2@@Z
符号(已解码)=public: class QPoint __cdecl QWidget::mapToGlobal(class QPoint const & __ptr64)const __ptr64
地址=00007FFF60F74AE0
类型=导出
序号=3953
符号=?isVisible@QWidget@@QEBA_NXZ
符号(已解码)=public: bool __cdecl QWidget::isVisible(void)const __ptr64
地址=00007FFF60FA2DE0
类型=导出
序号=5050
符号=?pos@QWidget@@QEBA?AVQPoint@@XZ
符号(已解码)=public: class QPoint __cdecl QWidget::pos(void)const __ptr64
地址=00007FFF60F84180
类型=导出
序号=7641
符号=?size@QWidget@@QEBA?AVQSize@@XZ
符号(已解码)=public: class QSize __cdecl QWidget::size(void)const __ptr64
*/
// using fnQApplication_topLevelWidgets = QListData * (_cdecl*)(void*);
var fnQApplication_topLevelWidgets = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?topLevelWidgets@QApplication@@SA?AV?$QList@PEAVQWidget@@@@XZ'),
'pointer',
['pointer'],
'win64'
);
var fnQWidget_x = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?x@QWidget@@QEBAHXZ'),
'int',
['pointer'],
'win64'
);
var fnQWidget_y = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?y@QWidget@@QEBAHXZ'),
'int',
['pointer'],
'win64'
);
var fnQWidget_mapFromGlobal = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?mapFromGlobal@QWidget@@QEBA?AVQPoint@@AEBV2@@Z'),
'pointer',
['pointer', 'pointer', 'pointer'],
'win64'
);
var fnQWidget_mapToGlobal = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?mapToGlobal@QWidget@@QEBA?AVQPoint@@AEBV2@@Z'),
'pointer',
['pointer', 'pointer', 'pointer'],
'win64'
);
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 获取相对于顶层窗口的坐标
function ez_fnQWidget_pos(obj) {
var qpoint_param = Memory.alloc(8);
try {
var ret = fnQWidget_pos(obj, qpoint_param);
var x = ret.add(0).readS32();
var y = ret.add(4).readS32();
// MyLogD('\t\t ez_fnQWidget_pos', qpoint_param.readU64().toString(16), ',x=', x, ',y=', y);
} catch (error) {
MyLogE('【catch】 ez_fnQWidget_pos', error);
}
return ret;
}
function ez_fnQWidget_mapFromGlobal(obj, point) {
var ret;
try {
var ret2 = Memory.alloc(8);
ret = fnQWidget_mapFromGlobal(obj, ret2, point);
var x = ret.add(0).readS32();
var y = ret.add(4).readS32();
MyLogD('\t\t ez_fnQWidget_mapFromGlobal', ret2.readU64().toString(16), ',x=', x, ',y=', y);
} catch (error) {
MyLogE('【catch】 ez_fnQWidget_mapFromGlobal', error, ret);
}
return ret;
}
function ez_fnQWidget_mapFromGlobal_x(obj) {
try {
var pos = ez_fnQWidget_pos(obj);
var pos2 = ez_fnQWidget_mapFromGlobal(obj, pos);
if (pos2) {
return pos2.readU64();
}
} catch (error) {
}
return -1;
}
function ez_fnQWidget_mapFromGlobal_y(obj) {
try {
var pos = ez_fnQWidget_pos(obj);
var pos2 = ez_fnQWidget_mapFromGlobal(obj, pos);
if (pos2) {
return pos2.add(4).readU64();
}
} catch (error) {
}
return -2;
}
function ez_fnQWidget_mapFromGlobal_xy(obj) {
try {
var pos = ez_fnQWidget_pos(obj);
// MyLogD('【 111 】 ez_fnQWidget_mapFromGlobal_xy', pos);
if(pos) {
var pos2 = ez_fnQWidget_mapFromGlobal(obj, pos);
// MyLogD('【 222 】 ez_fnQWidget_mapFromGlobal_xy', pos2);
if (pos2) {
// MyLogD('【 333 】 ez_fnQWidget_mapFromGlobal_xy', pos2);
return `${pos2.readS32()},${pos2.add(4).readS32()}`;
}
}
} catch (error) {
MyLogE('【catch】 ez_fnQWidget_mapFromGlobal_xy', error);
}
return `-1,-2`;
}
function ez_fnQWidget_mapToGlobal(obj, point) {
var ret2 = Memory.alloc(8);
try {
var ret = fnQWidget_mapToGlobal(obj, point, ret2);
// var x = ret.add(0).readS32();
// var y = ret.add(4).readS32();
// MyLogD('\t\t ez_fnQWidget_mapToGlobal', ret2.readU64().toString(16), ',x=', x, ',y=', y);
} catch (error) {
MyLogE('【catch】 ez_fnQWidget_mapToGlobal', error);
}
return ret2;
}
function ez_fnQWidget_mapToGlobal_xy(obj) {
try {
var pos = ez_fnQWidget_pos(obj);
// MyLogD('【 111 】 ez_fnQWidget_mapToGlobal_xy', pos);
if(pos) {
var pos2 = ez_fnQWidget_mapToGlobal(obj, pos);
// MyLogD('【 222 】 ez_fnQWidget_mapToGlobal_xy', pos2);
if (pos2) {
// MyLogD('【 333 】 ez_fnQWidget_mapToGlobal_xy', pos2);
return `${pos2.readS32()},${pos2.add(4).readS32()}`;
}
}
} catch (error) {
MyLogE('【catch】 ez_fnQWidget_mapToGlobal_xy', error);
}
return `-1,-2`;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
var fnQWidget_isVisible = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?isVisible@QWidget@@QEBA_NXZ'),
'bool',
['pointer'],
'win64'
);
var fnQWidget_pos = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?pos@QWidget@@QEBA?AVQPoint@@XZ'),
'pointer',
['pointer', 'pointer'],
'win64'
);
var fnQWidget_size = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?size@QWidget@@QEBA?AVQSize@@XZ'),
'pointer',
['pointer', 'pointer'],
'win64'
);
//////////////////////////////////////////////////////////////////////////////////////////
// Qt5Widgets
// - QLineEdit
// - QCheckBox
// - QAbstractButton
// - QLabel
//////////////////////////////////////////////////////////////////////////////////////////
/*
地址=00007FFF6109A430
类型=导出
序号=7323
符号=?setText@QLineEdit@@QEAAXAEBVQString@@@Z
符号(已解码)=public: void __cdecl QLineEdit::setText(class QString const & __ptr64) __ptr64
地址=00007FFF6109A840
类型=导出
序号=8169
符号=?textChanged@QLineEdit@@QEAAXAEBVQString@@@Z
符号(已解码)=public: void __cdecl QLineEdit::textChanged(class QString const & __ptr64) __ptr64
地址=00007FFF61058010
类型=导出
序号=6254
符号=?setCheckState@QCheckBox@@QEAAXW4CheckState@Qt@@@Z
符号(已解码)=public: void __cdecl QCheckBox::setCheckState(enum Qt::CheckState) __ptr64
地址=00007FFF6104B140
类型=导出
序号=6261
符号=?setChecked@QAbstractButton@@QEAAX_N@Z
符号(已解码)=public: void __cdecl QAbstractButton::setChecked(bool) __ptr64
地址=00007FFF61049580
类型=导出
序号=1850
符号=?click@QAbstractButton@@QEAAXXZ
符号(已解码)=public: void __cdecl QAbstractButton::click(void) __ptr64
地址=00007FFF6104B780
类型=导出
序号=8145
符号=?text@QAbstractButton@@QEBA?AVQString@@XZ
符号(已解码)=public: class QString __cdecl QAbstractButton::text(void)const __ptr64
地址=00007FFF610606C0
类型=导出
序号=8150
符号=?text@QLabel@@QEBA?AVQString@@XZ
符号(已解码)=public: class QString __cdecl QLabel::text(void)const __ptr64
*/
var fnQLineEdit_setText = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?setText@QLineEdit@@QEAAXAEBVQString@@@Z'),
'void',
['pointer', 'pointer'],
'win64'
);
var fnQLineEdit_textChanged = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?textChanged@QLineEdit@@QEAAXAEBVQString@@@Z'),
'void',
['pointer', 'pointer'],
'win64'
);
var fnQCheckBox_setCheckState = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?setCheckState@QCheckBox@@QEAAXW4CheckState@Qt@@@Z'),
'void',
['pointer', 'int'],
'win64'
);
var fnQAbstractButton_setChecked = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?setChecked@QAbstractButton@@QEAAX_N@Z'),
'void',
['pointer', 'bool'],
'win64'
);
var fnQAbstractButton_click = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?click@QAbstractButton@@QEAAXXZ'),
'void',
['pointer'],
'win64'
);
// fnQAbstractButton_click(ptr(my_read_u64(ptr(0xee7178).add(0x70))))
var fnQAbstractButton_text = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?text@QAbstractButton@@QEBA?AVQString@@XZ'),
'pointer',
['pointer', 'pointer'],
'win64'
);
function ez_fnQAbstractButton_text(obj) {
var s = ez_fnQString_fromUtf8('')
fnQAbstractButton_text(obj, s);
return QString2JsString(s)
}
var fnQLabel_text = new NativeFunction(
Module.findExportByName('Qt5Widgets.dll', '?text@QLabel@@QEBA?AVQString@@XZ'),
'void',
['pointer','pointer'],
'win64'
);
function ez_fnQLabel_text(obj) {
// var retQString = Memory.alloc(Process.pointerSize);
var retQString = ez_fnQString_fromUtf8('');
fnQLabel_text(obj, ptr(retQString));
MyLogD(retQString);
return my_read_u64_to_obj(retQString).add(0x10).readUtf16String();
}
var IsBadReadPtr = new NativeFunction(
Module.findExportByName('kernel32.dll', 'IsBadReadPtr'),
'bool',
['pointer', 'int'],
'win64'
);
function my_read_u32(addr) {
return ptr(addr.toString()).readU32()
}
function my_read_u64(addr) {
return ptr(addr.toString()).readU64()
}
function my_read_u64_to_obj(addr) {
return ptr(ptr(addr.toString()).readU64());
}
function fnGetWidgetsName(obj) {
try {
if (IsBadReadPtr(obj, 4)) {
return '';
}
if (IsBadReadPtr(
ptr(
'0x'+my_read_u64(obj.add(4)).toString(16)
), 4
)
) {
return '';
}
if (IsBadReadPtr(
ptr(my_read_u64(obj.add(4))).add(0x1c),
4)
) {
return '';
}
var p = Memory.alloc(4);
p.writeU32(0);
fnQObject_objectName(obj, p);
// console.log(typeof p, p, p.readU64(), p.readU64().toString(16), ptr(p.readU64()).readU64().toString(16))
// console.log(hexdump(ptr('0x'+p.readU64().toString(16)), {
// offset: 0,
// length: 0x20,
// header: true,
// ansi: false
// }));
return ptr('0x'+p.readU64().toString(16)).add(0x10).readUtf16String();
} catch {
MyLogE('【catch】 fnGetWidgetsName');
}
return ''
}
function getWidgetPosSize(obj) {
var qSzie_param = Memory.alloc(8);
try {
var qpoint_param = Memory.alloc(8);
var qpoint = fnQWidget_pos(obj, qpoint_param);
var x = qpoint.add(0).readU64();
var y = qpoint.add(4).readU64();
// MyLogD('\t\t', qpoint_param.readU64().toString(16), ',x=', x, ',y=', y);
var qSzie = fnQWidget_size(obj, qSzie_param);
} catch {
MyLogE('【catch】 getWidgetPosSize');
}
return qSzie_param;
}
function ez_QLineEdit_setText(obj, text) {
var qstr = ez_fnQString_fromUtf8(text);
fnQLineEdit_setText(obj, qstr);
// try {
// var qstr = ez_fnQString_fromUtf8('ez_QLineEdit_setText');
// fnQLineEdit_setText(obj, qstr);
// } catch {
// console.log('【catch】 ez_QLineEdit_setText');
// }
}
// ez_QLineEdit_setText(ptr(my_read_u64(ptr(0xe68a38).add(0x3c))))
function ez_fnQWidget_x(obj) {
try {
return fnQWidget_x(obj);
} catch (error) {
return -1;
}
}
function ez_fnQWidget_y(obj) {
try {
return fnQWidget_y(obj);
} catch (error) {
return -1;
}
}
//////////////////////////////////////////////////////////////////////////////////////////
// qt5webenginewidgets.dll / Qt5WebEngine.dll
// - QWebEnginePage
// -
//////////////////////////////////////////////////////////////////////////////////////////
/*
地址=00007FFA9AA2CE80
类型=导出
序号=283
符号=?runJavaScript@QWebEnginePage@@QEAAXAEBVQString@@@Z
符号(已解码)=public: void __cdecl QWebEnginePage::runJavaScript(class QString const & __ptr64) __ptr64
地址=00007FFA9AA2ADF0
类型=导出
序号=211
符号=?loadFinished@QWebEnginePage@@QEAAX_N@Z
符号(已解码)=public: void __cdecl QWebEnginePage::loadFinished(bool) __ptr64
WebEngineView QML Type
void runJavaScript(string script, variant callback)
地址=00007FFAAAEB43F0
类型=导出
序号=339
符号=?loadFinished@QQuickWebEngineViewPrivate@@UEAAX_NAEBVQUrl@@0HAEBVQString@@@Z
符号(已解码)=public: virtual void __cdecl QQuickWebEngineViewPrivate::loadFinished(bool,class QUrl const & __ptr64,bool,int,class QString const & __ptr64) __ptr64
地址=00007FFAAAEB5280
类型=导出
序号=527
符号=?runJavaScript@QQuickWebEngineView@@QEAAXAEBVQString@@AEBVQJSValue@@@Z
符号(已解码)=public: void __cdecl QQuickWebEngineView::runJavaScript(class QString const & __ptr64,class QJSValue const & __ptr64) __ptr64
class Q_QML_EXPORT QJSValue
{
public:
enum SpecialValue {
NullValue,
UndefinedValue
};
public:
QJSValue(SpecialValue value = UndefinedValue);
...
...
...
}
地址=00007FFAAAECBDD8
类型=导入
符号=qt5qml.??0QJSValue@@QEAA@W4SpecialValue@0@@Z
符号(已解码)=public: __cdecl QJSValue::QJSValue(enum QJSValue::SpecialValue) __ptr64
地址=00007FFAA1E7C450
类型=导入
符号=qt5webenginecore.?runJavaScript@WebContentsAdapter@QtWebEngineCore@@QEAAXAEBVQString@@I@Z
符号(已解码)=public: void __cdecl QtWebEngineCore::WebContentsAdapter::runJavaScript(class QString const & __ptr64,unsigned int) __ptr64
*/
var fnQWebEnginePage_runJavaScript = new NativeFunction(
Module.findExportByName('Qt5WebEngineWidgets.dll', '?runJavaScript@QWebEnginePage@@QEAAXAEBVQString@@@Z'),
'void',
['pointer', 'pointer'],
'win64'
);
var fnQJSValue_QJSValue = new NativeFunction(
Module.findExportByName('Qt5Qml.dll', '??0QJSValue@@QEAA@W4SpecialValue@0@@Z'),
'pointer',
['pointer', 'int'],
'win64'
);
function ez_gen_QJSValue_Undefined() {
var ret = Memory.alloc(Process.pointerSize);
fnQJSValue_QJSValue(ret, 1);
return ret;
}
var fnQQuickWebEngineView_runJavaScript = new NativeFunction(
Module.findExportByName('Qt5WebEngine.dll', '?runJavaScript@QQuickWebEngineView@@QEAAXAEBVQString@@AEBVQJSValue@@@Z'),
'void',
['pointer', 'pointer', 'pointer'],
'win64'
);
var fnWebContentsAdapter_runJavaScript = new NativeFunction(
Module.findExportByName('Qt5WebEngineCore.dll', '?runJavaScript@WebContentsAdapter@QtWebEngineCore@@QEAAXAEBVQString@@I@Z'),
'void',
['pointer', 'pointer', 'int'],
'win64'
);
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
"main": "src/index.ts", "main": "src/index.ts",
"scripts": { "scripts": {
"build": "frida-compile 04_frida_with_typescript/src/index.ts -o build/04.js -c", "build": "frida-compile 04_frida_with_typescript/src/index.ts -o build/04.js -c",
"watch02": "frida-compile 02_常见API示例及功能函数封装(snippets)/index.ts -o build/02.js -w",
"watch04": "frida-compile 04_frida_with_typescript/src/index.ts -o build/04.js -w", "watch04": "frida-compile 04_frida_with_typescript/src/index.ts -o build/04.js -w",
"watch05": "frida-compile ./05_读取棋盘数据/index.ts -o ./build/05.js -w", "watch05": "frida-compile ./05_读取棋盘数据/index.ts -o ./build/05.js -w",
"watch06": "frida-compile ./06_分析扫雷游戏的数据,显示地雷位置/index.ts -o ./build/06.js -w", "watch06": "frida-compile ./06_分析扫雷游戏的数据,显示地雷位置/index.ts -o ./build/06.js -w",
...@@ -13,7 +14,8 @@ ...@@ -13,7 +14,8 @@
"watch09": "frida-compile ./09_获取软件窗口位置,设置鼠标指针位置/index.ts -o ./build/09.js -w", "watch09": "frida-compile ./09_获取软件窗口位置,设置鼠标指针位置/index.ts -o ./build/09.js -w",
"watch10": "frida-compile ./10_设置鼠标位置,自动点击鼠标/index.ts -o ./build/10.js -w", "watch10": "frida-compile ./10_设置鼠标位置,自动点击鼠标/index.ts -o ./build/10.js -w",
"watch11": "frida-compile ./11_用鼠标自动标记棋盘上的雷区/index.ts -o ./build/11.js -w", "watch11": "frida-compile ./11_用鼠标自动标记棋盘上的雷区/index.ts -o ./build/11.js -w",
"runx": "D:/Python/Python371/Scripts/frida.exe -n winmine.exe -l ./build/11.js -q" "runx": "D:/Python/Python371/Scripts/frida.exe -n winmine.exe -l ./build/02.js -q",
"runx-debug": "D:/Python/Python371/Scripts/frida.exe -n winmine.exe -l ./build/02.js --debug --runtime=v8"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册