//RUNAS//窗口探测 import fonts.fontAwesome; import win.ui; /*DSG{{*/ var winform = win.form(text="窗口探测器";left=-2;top=100;right=688;bottom=526) winform.add( btnIlSpy={cls="plus";text=" .Net 程序 - 点这里反编译";left=310;top=32;right=485;bottom=56;align="left";color=0x800000;dl=1;dt=1;hide=1;iconColor=0x008000;iconStyle={align="left";font=LOGFONT(name='FontAwesome');padding={left=5}};iconText='\uF1C9';notify=1;textPadding={left=17};z=40}; chkHex={cls="checkbox";text="16 进制显示句柄";left=187;top=35;right=307;bottom=54;checked=1;dl=1;dt=1;z=36}; chkPassword={cls="checkbox";text="显示密码";left=422;top=119;right=501;bottom=138;dr=0.27;dt=1;z=30}; chkSkipDiabled={cls="checkbox";text="忽略禁用窗口";left=288;top=354;right=390;bottom=376;db=1;dl=1;z=35}; chkSkipInvisible={cls="checkbox";text="忽略隐藏窗口";left=183;top=355;right=285;bottom=376;checked=1;db=1;dl=1;z=34}; chkSkipTransparent={cls="checkbox";text="忽略透明窗口";left=77;top=354;right=179;bottom=376;db=1;dl=1;z=33}; chkUnicodeWindow={cls="plus";text="Unicode 窗口";left=76;top=32;right=179;bottom=57;align="left";dl=1;dt=1;iconStyle={align="left";font=LOGFONT(h=-15;name='FontAwesome')};iconText='\uF00D';textPadding={left=18};z=1}; editClass={cls="edit";left=77;top=151;right=214;bottom=172;dl=1;dt=1;edge=1;hidesel=1;readonly=1;tabstop=1;z=23}; editHwnd={cls="edit";left=77;top=9;right=167;bottom=32;dl=1;dt=1;edge=1;hidesel=1;multiline=1;readonly=1;tabstop=1;z=18}; editId={cls="edit";left=353;top=181;right=455;bottom=204;dl=1;dr=0.34;dt=1;edge=1;hidesel=1;readonly=1;tabstop=1;z=27}; editOwnerHwnd={cls="plus";text="0";left=373;top=12;right=463;bottom=26;align="left";color=0xFF0000;dl=1;dt=1;notify=1;z=17}; editParenHwnd={cls="plus";text="0";left=224;top=12;right=300;bottom=26;align="left";color=0xFF0000;dl=1;dt=1;notify=1;z=15}; editParentPid={cls="edit";left=194;top=90;right=244;bottom=111;dl=1;dt=1;edge=1;hidesel=1;readonly=1;tabstop=1;z=39}; editPath={cls="edit";left=77;top=57;right=494;bottom=80;dl=1;dr=0.28;dt=1;edge=1;hidesel=1;readonly=1;tabstop=1;z=19}; editPid={cls="edit";left=77;top=89;right=127;bottom=110;dl=1;dt=1;edge=1;hidesel=1;readonly=1;tabstop=1;z=20}; editPoint={cls="edit";left=77;top=181;right=298;bottom=204;dl=1;dt=1;edge=1;hidesel=1;readonly=1;tabstop=1;z=26}; editStyle={cls="edit";left=254;top=151;right=340;bottom=172;dl=1;dt=1;edge=1;hidesel=1;readonly=1;tabstop=1;z=24}; editStyleEx={cls="edit";left=406;top=151;right=494;bottom=172;dl=1;dr=0.28;dt=1;edge=1;hidesel=1;readonly=1;tabstop=1;z=25}; editText={cls="edit";left=77;top=119;right=412;bottom=142;dl=1;dr=0.4;dt=1;edge=1;hidesel=1;readonly=1;tabstop=1;z=22}; editTid={cls="edit";left=303;top=89;right=354;bottom=110;dl=1;dt=1;edge=1;hidesel=1;readonly=1;tabstop=1;z=21}; hotkey={cls="hotkey";left=306;top=391;right=430;bottom=411;db=1;dl=1;edge=1;z=29}; lbClass={cls="static";text="窗口类名:";left=0;top=153;right=73;bottom=170;align="right";dl=1;dt=1;z=5}; lbHwnd={cls="static";text="窗口句柄:";left=10;top=11;right=73;bottom=28;align="right";dl=1;dt=1;z=2}; lbId={cls="static";text="命令ID:";left=303;top=184;right=348;bottom=201;align="right";dl=1;dt=1;z=6}; lbOwner={cls="static";text="所有窗口:";left=300;top=11;right=359;bottom=28;align="right";dl=1;dt=1;z=16}; lbParenHwnd={cls="static";text="父窗口:";left=171;top=11;right=219;bottom=28;align="right";dl=1;dt=1;z=7}; lbPid={cls="static";text="进程ID:";left=26;top=91;right=73;bottom=113;align="right";dl=1;dt=1;z=10}; lbPoint={cls="static";text="窗口坐标:";left=3;top=184;right=73;bottom=201;align="right";dl=1;dt=1;z=13}; lbProcessInfo={cls="static";left=360;top=91;right=495;bottom=113;dl=1;dt=1;transparent=1;z=37}; lbStyle={cls="static";text="样式:";left=214;top=153;right=251;bottom=170;align="right";dl=1;dt=1;z=3}; lbStyleEx={cls="static";text="扩展样式:";left=340;top=153;right=402;bottom=170;align="right";dl=1;dt=1;z=4}; lbText={cls="static";text="窗口文本:";left=12;top=121;right=73;bottom=138;align="right";dl=1;dt=1;z=8}; lbTid={cls="static";text="线程ID:";left=251;top=91;right=297;bottom=113;align="right";dl=1;dt=1;z=9}; plusCur={cls="plus";left=22;top=380;right=54;bottom=412;background="\.res\1.gif";db=1;dl=1;notify=1;repeat="center";z=11}; richedit={cls="richedit";left=77;top=213;right=494;bottom=345;db=1;dl=1;dr=0.28;dt=1;edge=1;hscroll=1;multiline=1;tabstop=1;vscroll=1;z=28}; static={cls="static";text="启动文件:";left=5;top=59;right=73;bottom=76;align="right";dl=1;dt=1;z=12}; static2={cls="static";text="请拖动左侧瞄准器图标到目标窗口";left=64;top=392;right=293;bottom=417;db=1;dl=1;dr=1;z=14}; static3={cls="static";text="下级子窗口:";left=503;top=4;right=603;bottom=18;dl=0.73;dt=1;transparent=1;z=32}; static4={cls="static";text="父进程ID:";left=129;top=91;right=188;bottom=113;align="right";dl=1;dt=1;z=38}; treeview={cls="treeview";left=501;top=23;right=686;bottom=416;asel=false;bgcolor=0xFFFFFF;db=1;dl=0.73;dr=1;dt=1;edge=1;hscroll=1;vscroll=1;z=31} ) /*}}*/ import winex; import mouse; import process; import process.wmi; import win.ui.mask; var frmMask = win.ui.mask(winform); var numberToString = function(num){ if(winform.chkHex.checked) return string.format("0x%X",num ); return tostring(num) } var getParentHwnd = function(){ return tonumber(winform.editParenHwnd.text,winform.chkHex.checked?16:10) } var getOwnerHwnd = function(){ return tonumber(winform.editOwnerHwnd.text,winform.chkHex.checked?16:10) } import process.admin; import process.cmdline; import raw.pefile; function showWindowInfo(hwnd){ winform.editParenHwnd.text = numberToString(win.getParent(hwnd)); winform.editOwnerHwnd.text = numberToString(win.getOwner(hwnd)); winform.editHwnd.text = numberToString(hwnd); winform.editClass.text = win.getClass(hwnd) winform.editId.text = win.getId(hwnd); winform.chkUnicodeWindow.checked = winex.isUtf16(hwnd); var tid,pid = win.getThreadProcessId(hwnd) winform.editTid.text,winform.editPid.text = (tid),(pid); winform.editPath.text = process.cmdline(pid); var prcs = process(pid,0x400/*_PROCESS_QUERY_INFORMATION*/|0x10/*_PROCESS_VM_READ*/); if(prcs){ winform.lbProcessInfo.text = ((_WIN_64 && !prcs.isWow64()) ? "64位" : "32位") + "/" + (process.admin.isRunAs(prcs) ? "管理权限" : "普通权限"); var pid = prcs.getParentId(); winform.editParentPid.text = pid; winform.tooltipCtr.add(editParentPid=process.cmdline(pid):"") var path = prcs.getPath(); if(path && io.exist(path) ){ if(path!=winform.currentPePath){ var pe = raw.pefile(path); if(pe && pe.getClrHeader()){ winform.btnIlSpy.hide = false; } else { winform.btnIlSpy.hide = true; } } } else { winform.btnIlSpy.hide = true; } winform.currentPePath = path; prcs.free(); } else { winform.btnIlSpy.hide = true; } var str = winex.getText(hwnd,50); if(#str){ winform.editText.text = string.replace(str,"[\r\n]","") } else { if( winform.chkPassword.checked && winform.editClass.text == "Edit" && ..win.getStyle(hwnd,0x40000000/*_WS_CHILD*/) && ..win.getStyle(hwnd,0x20/*_ES_PASSWORD*/) && !..win.isChild(winform.hwnd,hwnd) ){ if( hwnd != winform.lastSpyHwnd && winform.editText.text == ""){ var tid,pid = win.getThreadProcessId(hwnd) var tid2,pid2 = win.getThreadProcessId(winform.hwnd); if( pid2 != pid ){ var prcs = process( pid ) if(prcs){ var tid,pid = win.getThreadProcessId(hwnd); var prcs = process( pid ); var getWindowText = prcs.remoteApi("int(addr hwnd,ustring& lpString,int cch)" ,"User32.dll","GetWindowTextW" ) if(getWindowText){ var len,str = getWindowText(hwnd,400,200); if(len) winform.editText.text = str; } prcs.free(); } } } } else { winform.editText.text = ""; } } winform.editStyle.text = numberToString(win.getStyle(hwnd) ); winform.editStyleEx.text = numberToString(win.getStyleEx(hwnd) ); var x,y = mouse.getPos(); x,y = win.toClient(hwnd,x,y); winform.editPoint.text = ..string.format("%d,%d",x,y) winform.treeview.clear(); var hRootItem = winform.treeview.insertItem({text=..win.getClass(hwnd);hwnd=hwnd}); for hChild in win.eachChild(hwnd) { var hChildItem = winform.treeview.insertItem({text=..win.getClass(hChild);hwnd=hChild},hRootItem); for hChild2 in win.eachChild(hChild) { winform.treeview.insertItem({text=..win.getClass(hChild2);hwnd=hChild2},hChildItem); } } if(hRootItem) winform.treeview.expand(hRootItem); winform.showSampleCode(); winform.lastSpyHwnd = hwnd; } winform.treeview.onnotify = function(id,code,ptr){ if( code == 0xFFFFFFFE/*_NM_CLICK*/){ var hItem,tvht = winform.treeview.hitTest(); if(hItem && tvht == 4/*_TVHT_ONITEMLABEL*/ ){ var data = winform.treeview.getItemData(hItem); if( data[["hwnd"]] ) { winform.setTimeout( function(){ if( frmMask.moveToWindow(data[["hwnd"]]) ){ showWindowInfo(data[["hwnd"]]); win.delay(600); frmMask.show(false); } } ); } } } } var validPattern = function(str){ if(!#str) return ""; var mbs = string.match(str,"[ \t\w]*:+[ \t\w]*") if(#mbs) return mbs; str = string.replace(str,"(\p)","\\\1") str = string.replace(str,'\n',"\\n") str = string.replace(str,'\r',"\\r") str = string.replace(str,"\x+",function(str){ if(..string.find(str,"\d") ) return "\x+" return str; } ) str = string.replace(str,"\d+","\\d+") return str; } winform.showSampleCode = function(){ var hwnd = tonumber(winform.editHwnd.text); if(!hwnd) return; winform.richedit.text = ""; winform.richedit.print("import winex"); winform.richedit.print("import winex.mouse"); if( win.getParent(hwnd) ){ var hwndRoot = win.getRoot(hwnd); var pClass,pText = validPattern(win.getClass(hwnd)) ,validPattern(winex.getText(hwnd,50)); var pClass2,pText2 = validPattern(win.getClass(hwndRoot)) ,validPattern(winex.getText(hwndRoot,50)); winform.richedit.printf('var hwndParent = winex.find("%s","%s");\r\nvar hwnd = winex.findEx(hwndParent,,"%s","%s");',pClass2,pText2,pClass,pText); } else{ if( win.getOwner(hwnd) ){ winform.richedit.printf("var hwnd = winex.waitEx(%d,,""%s"",""%s"")", win.getOwner(hwnd),validPattern(win.getClass(hwnd)),validPattern(winex.getText(hwnd,50))); } else { winform.richedit.printf("var hwnd = winex.waitVisible(""%s"",,""%s"")", validPattern(winex.getText(hwnd,50)),validPattern(win.getClass(hwnd))); } } winform.richedit.printf("winex.mouse.click(hwnd,%s)",winform.editPoint.text); } winform.plusCur.skin( background = { active = "\.res\2.gif"; } ) import win.cur; var hCursor = win.cur.loadfile("\.res\spy.cur") ; winform.plusCur.onMouseDown = function(wParam,lParam){ win.cur.beginCur(); winform.plusCur.capture = true; winform.lastSpyHwnd = null; } winform.plusCur.onMouseUp = function(wParam,lParam){ winform.plusCur.capture = false; win.cur.endCur(); frmMask.show(false); } var hwndTarget; tmid = winform.setInterval( function(hwnd,msg,id,tick){ if ( win.cur.beginning ){ var cwp = 0; if( winform.chkSkipInvisible.checked ) cwp = cwp | 0x0001/*_CWP_SKIPINVISIBLE*/ if( winform.chkSkipTransparent.checked ) cwp = cwp | 0x0004/*_CWP_SKIPTRANSPARENT*/ if( winform.chkSkipDiabled.checked ) cwp = cwp | 0x0002/*_CWP_SKIPDISABLED*/ var x,y = mouse.getPos(); hwndTarget = winex.fromPointReal( x,y,cwp ); if( frmMask.moveToWindow(hwndTarget) ){ showWindowInfo(hwndTarget); } } },700 ) winform.editParenHwnd.skin( color = { hover = 0xFFFF0000; active = 0xFF00FF00; } ) winform.editOwnerHwnd.skin( color = { hover = 0xFFFF0000; active = 0xFF00FF00; } ) winform.editParenHwnd.oncommand = function(id,event){ var hwnd = getParentHwnd() if(hwnd){ if( frmMask.moveToWindow(hwnd) ){ showWindowInfo(hwnd); win.delay(600); frmMask.show(false); } } } winform.editOwnerHwnd.oncommand = function(id,event){ var hwnd = getOwnerHwnd() if(hwnd){ if( frmMask.moveToWindow(hwnd) ){ showWindowInfo(hwnd); ..win.delay(600); frmMask.show(false); } } } import fsys.config; config = fsys.config("/.res/config-winspy/"); if( config.hotkey.vk === null ){ config.hotkey.vk = 0x7B/*_VK_F12*/; config.hotkey.mod = 0x2/*_MOD_CONTROL*/ } winform.hotkey.sethotkey(config.hotkey.mod,config.hotkey.vk) var onHotkey = function(){ winform.lastSpyHwnd = null; var cwp = 0; if( winform.chkSkipInvisible.checked ) cwp = cwp | 0x0001/*_CWP_SKIPINVISIBLE*/ if( winform.chkSkipTransparent.checked ) cwp = cwp | 0x0004/*_CWP_SKIPTRANSPARENT*/ if( winform.chkSkipDiabled.checked ) cwp = cwp | 0x0002/*_CWP_SKIPDISABLED*/ var x,y = mouse.getPos(); hwndTarget = winex.fromPointReal( x,y,cwp ); if( hwndTarget == getParentHwnd() ){ hwndTarget = getParentHwnd(); if(hwndTarget){ showWindowInfo(hwndTarget); winform.plusCur.background = "\.res\1.gif" win.cur.endCur(); frmMask.show(false); return; } } elseif( hwndTarget == getOwnerHwnd() ){ hwndTarget = getOwnerHwnd(); if(hwndTarget){ showWindowInfo(hwndTarget); winform.plusCur.background = "\.res\1.gif" win.cur.endCur(); frmMask.show(false); return; } }; if( win.cur.beginning){ winform.plusCur.background = "\.res\1.gif" win.cur.endCur(); frmMask.show(false); } else { win.cur.beginCur(); winform.plusCur.background = "\.res\2.gif" } } var hkid = winform.reghotkey(onHotkey,config.hotkey.mod,config.hotkey.vk); winform.hotkey.oncommand = function(id,event){ winform.unreghotkey(hkId); hkId = winform.reghotkey(onHotkey,winform.hotkey.gethotkey() ); config.hotkey.mod,config.hotkey.vk = winform.hotkey.gethotkey(); config.hotkey.save(); } win.setTopmost(winform.hwnd,true); import win.clip; winform.editStyle.translateAccelerator = function(msg){ var vk = msg.wParam; if( (vk = 'V'# ) && (::GetKeyState(0x11/*_VK_CONTROL*/)&0x8000)){ if( msg.message == 0x100/*_WM_KEYDOWN*/) { var str = win.clip.read(); if(tonumber(str)){ winform.editStyle.text = str; winform.editStyle.onFocusGot(); } return true; } } } winform.editStyle.onFocusGot = function(){ if(owner.text==""){ var str = win.clip.read(); if(tonumber(str)){ owner.text = str; owner.onFocusGot(); } return; } winform.richedit.text = ""; var style = { _WS_POPUP = 0x80000000; _WS_CHID = 0x40000000; _WS_MINIMIZE = 0x20000000; _WS_VISIBLE = 0x10000000; _WS_DISABED = 0x8000000; _WS_CLIPSIBLINGS = 0x4000000; _WS_CLIPCHILDREN = 0x2000000; _WS_MAXIMIZE = 0x1000000; _WS_BORDER = 0x800000; _WS_DLGFRAME = 0x400000; _WS_VSCROLL = 0x200000; _WS_HSCROLL = 0x100000; _WS_SYSMENU = 0x80000; _WS_MINIMIZEBOX = 0x20000; _WS_MAXIMIZEBOX = 0x10000; _WS_GROUP = 0x20000; _WS_TABSTOP = 0x10000; ["_WS_SIZEBOX(_WS_THICKFRAME)"] = 0x40000; ["_WS_CAPTION(_WS_DLGFRAME | _WS_BORDER)"] = 0xC00000; } var dumpWindowStyle = function(s){ if( ! ( s&0x80000000 || s&0x40000000 ) ){ winform.richedit.print("_WS_OVERLAPPED") } for(k,v in style){ if( (v & s) == v) { if((v==0x400000/*_WS_DLGFRAME*/||v==0x800000/*_WS_BORDER*/) && (s & 0xC00000/*_WS_CAPTION*/)){ /* _WS_BORDER 样式显示边框 _WS_CAPTION 样式显示标题栏 _WS_CAPTION == _WS_DLGFRAME | _WS_BORDER 因为 _WS_CAPTION 包含 _WS_BORDER 所以有标题栏的窗口一定有边框,而无边框的窗口一定没有标题栏。 窗口边框样式有四种: - _WS_BORDER 细边框 - _WS_DLGFRAME 或 _WS_CAPTION 对话框风格边框 - _WS_SIZEBOX( 或 _WS_THICKFRAME) 可拖动调整大小边框 - 无边框 */ } elseif( (k=="_WS_GROUP" || k=="_WS_TABSTOP")) && !(s & 0x40000000){ } elseif( (k=="_WS_MINIMIZEBOX" || k=="_WS_MAXIMIZEBOX")) && (s & 0x40000000){ } else { winform.richedit.print(k) } } } } var s = tonumber(winform.editStyle.text); if(!s) return; dumpWindowStyle(s); }; winform.editStyleEx.translateAccelerator = function(msg){ var vk = msg.wParam; if( (vk = 'V'# ) && (::GetKeyState(0x11/*_VK_CONTROL*/)&0x8000)){ if( msg.message == 0x100/*_WM_KEYDOWN*/) { var str = win.clip.read(); if(tonumber(str)){ winform.editStyleEx.text = str; winform.editStyleEx.onFocusGot(); } return true; } } } winform.editStyleEx.onFocusGot = function(){ if(owner.text==""){ var str = win.clip.read(); if(tonumber(str)){ owner.text = str; owner.onFocusGot(); } return; } winform.richedit.text = ""; var style={ _WS_EX_DLGMODALFRAME = 0x1; _WS_EX_NOPARENTNOTIFY = 0x4; _WS_EX_TOPMOST = 0x8; _WS_EX_ACCEPTFILES = 0x10; _WS_EX_TRANSPARENT = 0x20; _WS_EX_MDICHILD = 0x40; _WS_EX_TOOLWINDOW = 0x80; _WS_EX_WINDOWEDGE = 0x100; _WS_EX_CLIENTEDGE = 0x200; _WS_EX_CONTEXTHELP = 0x400; _WS_EX_RIGHT = 0x1000; _WS_EX_RTLREADING = 0x2000; _WS_EX_LEFTSCROLLBAR = 0x4000; _WS_EX_CONTROLPARENT = 0x10000; _WS_EX_STATICEDGE = 0x20000; _WS_EX_APPWINDOW = 0x40000; _WS_EX_LAYERED = 0x80000; _WS_EX_NOINHERITLAYOUT = 0x100000; _WS_EX_LAYOUTRTL = 0x400000; _WS_EX_COMPOSITED = 0x2000000; _WS_EX_NOACTIVATE = 0x8000000; } var s = tonumber(winform.editStyleEx.text); if(!s) return; for(k,v in style){ if( v & s) winform.richedit.print(k) } }; winform.editClass.oncommand = function(id,event){ winform.showSampleCode(); } winform.editHwnd.oncommand = function(id,event){ winform.showSampleCode(); } winform.editText.oncommand = function(id,event){ winform.showSampleCode(); } winform.editPoint.oncommand = function(id,event){ winform.showSampleCode(); } import win.ui.tooltip; winform.tooltipCtr = win.ui.tooltip( winform );//在窗口上创建tooltip控件 winform.tooltipCtr.add( plusCur = "请按住此图标并拖动到目标窗口"; editParenHwnd = "点击这里切换到父窗口(parent window),也可以将鼠标指针对准这里按下面设置的热键切换到父窗口"; editOwnerHwnd = "点击这里切换到所有窗口(owner window),也可以将鼠标指针对准这里按下面设置的热键切换到所有窗口"; editStyle = "点这里显示详细的样式列表"; editStyleEx = "点这里显示详细的扩展样式列表"; editClass = "点这里显示演示代码"; editText = "点这里显示演示代码"; hotkey = "设置抓取窗口的热键,按此热键可以开始、或停止抓取窗口,适用于抓取弹出窗口"; editPath = "启动目标应用程序的执行文件路径与启动参数"; editPoint = "相对于父窗口的坐标,点这里显示演示代码"; editPid = "这是窗口所在目标进程的10进制ID,进程是正在运行的程序的实例,也就是一个执行中的程序。每一个进程都有它自己的地址空间,在一个进程中可以包含若干个执行线程"; editTid= "这是窗口所在执行线程的10进制ID,线程被包含在进程(执行中的程序实例)之中,一个执行线程指的是进程中一个单一顺序的控制流,一个进程中可以并发执行多个线程"; editHwnd = "句柄是一个系统对象的唯一标识,在 aardio 中窗口句柄是一个数值(原生类型为 addr ),其他类型句柄一般用指针表示( 原生类型 pointer ),当然他们的本质都是数值。"; editId = "控件的 ID 值"; chkHex = "是否以16进制显示窗口句柄与样式" ); winform.chkHex.oncommand = function(id,event){ var hwnd = tonumber(winform.editHwnd.text) if(hwnd){ showWindowInfo(hwnd); } } winform.btnIlSpy.oncommand = function(id,event){ import dotNet.ilSpy; dotNet.ilSpy(winform.currentPePath); } winform.btnIlSpy.skin({ color={ active=0xFF00FF00; default=0xFF000080; disabled=0xFF6D6D6D; hover=0xFFFF0000 } }) winform.chkUnicodeWindow.skin({ color={ disabled=0xFF000000; }; iconColor = { default =0xFFFF4500} checked={ iconText='\uF00C'; iconColor = { default = 0xFF228B22} } }) winform.chkUnicodeWindow.disabled = true; winform.richedit.enablePopMenu(); winform.show(true); win.loopMessage();