LunaHook-mirror/LunaHost/GUI/LunaHost.cpp

280 lines
9.8 KiB
C++
Raw Normal View History

2024-02-07 20:59:24 +08:00
#include <CommCtrl.h>
#include <TlHelp32.h>
#include<stdio.h>
2024-02-09 09:25:26 +08:00
#include<fstream>
2024-02-07 20:59:24 +08:00
#include"host.h"
#include"hookcode.h"
#include"textthread.h"
#include"LunaHost.h"
#include"processlistwindow.h"
#include"Lang/Lang.h"
void LunaHost::toclipboard(std::wstring& sentence){
for (int loop = 0; loop < 10; loop++) {
if (OpenClipboard(winId)) {
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, (sentence.size() + 2) * sizeof(wchar_t));
memcpy(GlobalLock(hMem), sentence.c_str(), (sentence.size() + 2) * sizeof(wchar_t));
EmptyClipboard();
SetClipboardData(CF_UNICODETEXT, hMem);
GlobalUnlock(hMem);
CloseClipboard();
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}
void LunaHost::on_close(){
2024-02-09 09:25:26 +08:00
delete configs;
2024-02-07 20:59:24 +08:00
for(auto pid:attachedprocess){
Host::DetachProcess(pid);
}
2024-02-09 09:25:26 +08:00
Sleep(100);
2024-02-07 20:59:24 +08:00
}
void LunaHost::on_size(int w,int h){
int height = h-140;
2024-02-09 09:25:26 +08:00
w-=20;
g_selectprocessbutton->setgeo(10,10,w/3,40);
btnshowsettionwindow->setgeo(10+w/3,10,w/3,40);
btnplugin->setgeo(10+w*2/3,10,w/3,40);
g_hListBox_listtext->setgeo(10, 110, w , height/2);
g_showtexts->setgeo(10, 120+height/2, w , height/2);
g_hEdit_userhook->setgeo(10,60,w*2/3,40);
g_hButton_insert->setgeo(10+w*2/3,60,w/3,40);
2024-02-07 20:59:24 +08:00
}
LunaHost::LunaHost(){
2024-02-09 09:25:26 +08:00
configs=new confighelper;
2024-02-07 20:59:24 +08:00
settext(WndLunaHostGui);
2024-02-09 09:25:26 +08:00
btnshowsettionwindow=new button(this, BtnShowSettingWindow,100,100,100,100);
2024-02-08 16:18:33 +08:00
g_selectprocessbutton =new button(this,BtnSelectProcess,830, 10, 200, 40) ;
2024-02-07 20:59:24 +08:00
g_hEdit_userhook = new textedit(this,L"",10, 60, 600, 40,ES_AUTOHSCROLL);
2024-02-09 09:25:26 +08:00
btnplugin=new button(this,BtnPlugin,830,60,200,40);
plugins=new Pluginmanager(this);
btnplugin->onclick=[&](){
if(pluginwindow==0) pluginwindow=new Pluginwindow(this,plugins);
pluginwindow->show();
2024-02-08 16:18:33 +08:00
};
2024-02-07 20:59:24 +08:00
g_hButton_insert = new button(this,BtnInsertUserHook,610, 60, 200, 40) ;
2024-02-09 09:25:26 +08:00
btnshowsettionwindow->onclick=[&](){
if(settingwindow==0) settingwindow=new Settingwindow(this);
settingwindow->show();
};
2024-02-07 20:59:24 +08:00
g_selectprocessbutton->onclick=[&](){
if(_processlistwindow==0) _processlistwindow=new processlistwindow(this);
_processlistwindow->show();
};
g_hButton_insert->onclick=[&](){
auto hp = HookCode::Parse(std::move(g_hEdit_userhook->text()));
if(hp){
for(auto _:attachedprocess){
Host::InsertHook(_,hp.value());
}
}
else{
g_showtexts->appendtext(NotifyInvalidHookCode);
}
};
g_hListBox_listtext = new listbox(this,10, 120, 200, 200);
g_hListBox_listtext->oncurrentchange=[&](int idx){
uint64_t handle = g_hListBox_listtext->getdata(idx);
std::wstring get;
for(auto& _:savetext.at(handle)){
get+=_;
get+=L"\r\n";
}
currentselect=handle;
g_showtexts->settext(get);
g_showtexts->scrolltoend();
};
#define IDM_REMOVE_HOOK 1001
#define IDM_DETACH_PROCESS 1002
#define IDM_COPY_HOOKCODE 1003
g_hListBox_listtext->oncontextmenu=[](){
HMENU hMenu = CreatePopupMenu();
AppendMenu(hMenu, MF_STRING, IDM_COPY_HOOKCODE, MenuCopyHookCode);
AppendMenu(hMenu, MF_STRING, IDM_REMOVE_HOOK, MenuRemoveHook);
AppendMenu(hMenu, MF_STRING, IDM_DETACH_PROCESS, MenuDetachProcess);
return hMenu;
};
g_hListBox_listtext->oncontextmenucallback=[&](WPARAM wparam){
2024-02-08 16:18:33 +08:00
auto handle = g_hListBox_listtext->getdata(g_hListBox_listtext->currentidx());
auto tt=Host::GetThread(handle);
if(tt==0)return;
2024-02-07 20:59:24 +08:00
switch (LOWORD(wparam)) {
case IDM_COPY_HOOKCODE:
2024-02-08 16:18:33 +08:00
toclipboard(std::wstring(tt->hp.hookcode));
2024-02-07 20:59:24 +08:00
break;
case IDM_DETACH_PROCESS:
2024-02-08 16:18:33 +08:00
Host::DetachProcess(tt->tp.processId);
2024-02-07 20:59:24 +08:00
break;
case IDM_REMOVE_HOOK:
2024-02-08 16:18:33 +08:00
Host::RemoveHook(tt->tp.processId,tt->tp.addr);
2024-02-07 20:59:24 +08:00
break;
}
};
g_showtexts = new textedit(this,L"",10, 330, 200, 200,ES_READONLY|ES_MULTILINE |ES_AUTOVSCROLL| WS_VSCROLL);
2024-02-08 16:18:33 +08:00
2024-02-09 09:59:49 +08:00
TextThread::filterRepetition=configs->get("filterrepeat",false);
check_toclipboard=configs->get("ToClipboard",false);
TextThread::flushDelay=configs->get("flushDelay",TextThread::flushDelay);
Host::defaultCodepage=configs->get("codepage",Host::defaultCodepage);
2024-02-07 20:59:24 +08:00
Host::Start(
[&](DWORD pid) {attachedprocess.push_back(pid);},
[&](DWORD pid) {
attachedprocess.erase(std::remove(attachedprocess.begin(), attachedprocess.end(), pid), attachedprocess.end());
},
2024-02-08 16:18:33 +08:00
std::bind(&LunaHost::on_thread_create,this,std::placeholders::_1),
std::bind(&LunaHost::on_thread_delete,this,std::placeholders::_1),
std::bind(&LunaHost::on_text_recv,this,std::placeholders::_1,std::placeholders::_2)
2024-02-07 20:59:24 +08:00
);
2024-02-09 09:25:26 +08:00
setfont(25);
setcentral(1000,600);
2024-02-08 16:18:33 +08:00
}
bool LunaHost::on_text_recv(TextThread& thread, std::wstring& output){
std::lock_guard _(settextmutex);
2024-02-08 19:12:20 +08:00
if(!plugins->dispatch(thread,output))return false;
2024-02-09 09:40:07 +08:00
strReplace(output,L"\n",L"\r\n");
savetext.at(thread.handle).push_back(output);
2024-02-08 16:18:33 +08:00
if(currentselect==thread.handle){
g_showtexts->scrolltoend();
2024-02-09 09:40:07 +08:00
g_showtexts->appendtext(output);
2024-02-08 16:18:33 +08:00
}
return true;
}
void LunaHost::on_thread_create(TextThread& thread){
wchar_t buff[65535];
swprintf_s(buff,L"[%I64X:%I32X:%I64X:%I64X:%I64X:%s:%s]",
thread.handle,
thread.tp.processId,
thread.tp.addr,
thread.tp.ctx,
thread.tp.ctx2,
thread.name.c_str(),
thread.hp.hookcode
);
savetext.insert({thread.handle,{}});
int index=g_hListBox_listtext->additem(buff);
g_hListBox_listtext->setdata(index,thread.handle);
}
void LunaHost::on_thread_delete(TextThread& thread){
int count = g_hListBox_listtext->count();
for (int i = 0; i < count; i++) {
uint64_t handle = g_hListBox_listtext->getdata(i);
if (handle== thread.handle) {
g_hListBox_listtext->deleteitem(i);
break;
}
}
2024-02-09 09:25:26 +08:00
}
Settingwindow::Settingwindow(LunaHost* host):mainwindow(host){
new label(this,LblFlushDelay,10, 10, 150, 40);
new label(this,LblCodePage,10, 60, 150, 40);
ckbfilterrepeat=new checkbox(this,LblFilterRepeat,10, 160, 200, 40);
ckbfilterrepeat->onclick=[=](){
auto ck=ckbfilterrepeat->ischecked();
TextThread::filterRepetition=ck;
host->configs->set("filterrepeat",ck);
};
2024-02-09 09:59:49 +08:00
ckbfilterrepeat->setcheck(host->configs->get("filterrepeat",false));
2024-02-09 09:25:26 +08:00
g_check_clipboard =new checkbox(this,BtnToClipboard,10, 110, 200, 40) ;
g_check_clipboard->onclick=[=](){
auto ck=g_check_clipboard->ischecked();
((LunaHost*)parent)->check_toclipboard=ck;
host->configs->set("ToClipboard",ck);
2024-02-09 09:59:49 +08:00
};
g_check_clipboard->setcheck(host->configs->get("ToClipboard",false));
2024-02-09 09:25:26 +08:00
g_timeout = new textedit(this,std::to_wstring(host->configs->get("flushDelay",TextThread::flushDelay)).c_str(),160, 10, 100, 40) ;
g_codepage = new textedit(this,std::to_wstring(host->configs->get("codepage",Host::defaultCodepage)).c_str(),160, 60, 100, 40) ;
g_timeout->ontextchange=[=](const std::wstring &text){
try{
auto fla=std::stoi(text);
TextThread::flushDelay=fla;
host->configs->set("flushDelay",fla);
}
catch(std::exception&){}
};
2024-02-09 09:59:49 +08:00
2024-02-09 09:25:26 +08:00
g_codepage->ontextchange=[=](const std::wstring &text){
try {
auto cp=std::stoi(text);
if(IsValidCodePage(cp)){
2024-02-09 09:59:49 +08:00
Host::defaultCodepage= cp;
printf("%d",Host::defaultCodepage);
2024-02-09 09:25:26 +08:00
host->configs->set("codepage",cp);
}
}
catch (const std::invalid_argument& e) {
}
2024-02-09 09:59:49 +08:00
};
2024-02-09 09:25:26 +08:00
setcentral(300,300);
settext(WndSetting);
}
void Pluginwindow::on_size(int w,int h){
listplugins->setgeo(10,80,w-20,h-100);
}
Pluginwindow::Pluginwindow(mainwindow*p,Pluginmanager* pl):mainwindow(p){
pluginmanager=pl;
new label(this,LblPluginNotify, 10,10,500,30);
new label(this,LblPluginRemove, 10,40,500,30);
static auto listadd=[&](const std::wstring& s){
auto idx=listplugins->additem(std::filesystem::path(s).stem().c_str());
listplugins->setdata(idx,(LONG_PTR)s.c_str());
};
listplugins = new listbox(this,10, 10,360,340);
#define IDM_ADD_PLUGIN 1004
#define IDM_ADD_QT_PLUGIN 1005
#define IDM_REMOVE_PLUGIN 1006
listplugins->oncontextmenu=[](){
HMENU hMenu = CreatePopupMenu();
AppendMenu(hMenu, MF_STRING, IDM_ADD_PLUGIN, MenuAddPlugin);
AppendMenu(hMenu, MF_STRING, IDM_ADD_QT_PLUGIN, MenuAddQtPlugin);
AppendMenu(hMenu, MF_STRING, IDM_REMOVE_PLUGIN, MenuRemovePlugin);
return hMenu;
};
listplugins->oncontextmenucallback=[&](WPARAM wparam){
listplugins->currentidx() ;
switch (LOWORD(wparam)) {
case IDM_ADD_PLUGIN:
case IDM_ADD_QT_PLUGIN:
{
auto f=pluginmanager->selectpluginfile();
if(f.has_value()){
if(pluginmanager->addplugin(f.value(),LOWORD(wparam)==IDM_ADD_QT_PLUGIN)){
listadd(f.value());
}
}
break;
}
case IDM_REMOVE_PLUGIN:
{
auto idx=listplugins->currentidx();
2024-02-09 09:47:22 +08:00
if(idx==0)break;
2024-02-09 09:25:26 +08:00
pluginmanager->remove((LPCWSTR)listplugins->getdata(idx));
2024-02-09 09:47:22 +08:00
listplugins->deleteitem(idx-1);
2024-02-09 09:25:26 +08:00
break;
}
}
};
for(int i=0;i<pluginmanager->PluginRank.size();i++){
listadd(pluginmanager->PluginRank[i]);
}
settext(WndPlugins);
setcentral(500,400);
2024-02-07 20:59:24 +08:00
}