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 __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' );