2015-04-02 22:27:58 +08:00
|
|
|
/* Copyright (C) 2010-2012 kaosu (qiupf2000@gmail.com)
|
|
|
|
* This file is part of the Interactive Text Hooker.
|
|
|
|
|
|
|
|
* Interactive Text Hooker is free software: you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License as published
|
|
|
|
* by the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
#include "window.h"
|
|
|
|
#include "ProcessWindow.h"
|
|
|
|
#include "resource.h"
|
|
|
|
#include "language.h"
|
2016-01-05 23:01:17 +08:00
|
|
|
#include "host/host.h"
|
|
|
|
#include "host/hookman.h"
|
|
|
|
#include "vnrhook/include/const.h"
|
2015-04-02 22:27:58 +08:00
|
|
|
#include "version.h"
|
|
|
|
#include "ProfileManager.h"
|
2016-01-05 23:01:17 +08:00
|
|
|
#include "profile/Profile.h"
|
2015-04-02 22:27:58 +08:00
|
|
|
#include "TextBuffer.h"
|
2016-01-05 23:01:17 +08:00
|
|
|
#include "profile/misc.h"
|
2015-04-02 22:27:58 +08:00
|
|
|
|
|
|
|
#define CMD_SIZE 512
|
|
|
|
|
|
|
|
static WNDPROC proc, proccmd, procChar;
|
|
|
|
static WCHAR last_cmd[CMD_SIZE];
|
|
|
|
extern HINSTANCE hIns; // main.cpp
|
|
|
|
|
|
|
|
HWND hMainWnd, hwndCombo, hwndProcessComboBox, hwndEdit, hwndCmd;
|
|
|
|
HWND hwndProcess;
|
2018-07-13 23:47:16 +08:00
|
|
|
HWND hwndOption, hwndTop, hwndClear, hwndSave, hwndExtensions, hwndRemoveHook;
|
2015-04-02 22:27:58 +08:00
|
|
|
HWND hProcDlg, hOptionDlg;
|
|
|
|
HBRUSH hWhiteBrush;
|
|
|
|
DWORD background;
|
|
|
|
ProcessWindow* pswnd;
|
|
|
|
TextBuffer* texts;
|
|
|
|
extern ProfileManager* pfman; // ProfileManager.cpp
|
|
|
|
extern HookManager* man; // main.cpp
|
|
|
|
#define COMMENT_BUFFER_LENGTH 512
|
|
|
|
static WCHAR comment_buffer[COMMENT_BUFFER_LENGTH];
|
|
|
|
|
|
|
|
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
|
|
|
void SaveSettings(); // main.cpp
|
|
|
|
extern LONG split_time, process_time, inject_delay, insert_delay,
|
2016-01-05 23:01:17 +08:00
|
|
|
auto_inject, auto_insert, clipboard_flag, cyclic_remove, global_filter; //main.cpp
|
2015-04-02 22:27:58 +08:00
|
|
|
static int last_select, last_edit;
|
|
|
|
|
|
|
|
ATOM MyRegisterClass(HINSTANCE hInstance)
|
|
|
|
{
|
|
|
|
WNDCLASSEX wcex;
|
|
|
|
wcex.cbSize = sizeof(WNDCLASSEX);
|
2016-01-05 23:01:17 +08:00
|
|
|
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
|
|
|
wcex.lpfnWndProc = WndProc;
|
|
|
|
wcex.cbClsExtra = 0;
|
|
|
|
wcex.cbWndExtra = 0;
|
|
|
|
wcex.hInstance = hInstance;
|
|
|
|
wcex.hIcon = NULL;
|
|
|
|
wcex.hCursor = NULL;
|
|
|
|
wcex.hbrBackground = GetStockBrush(WHITE_BRUSH);
|
|
|
|
wcex.lpszMenuName = NULL;
|
|
|
|
wcex.lpszClassName = ClassName;
|
|
|
|
wcex.hIconSm = LoadIcon(hInstance, (LPWSTR)IDI_ICON1);
|
2015-04-02 22:27:58 +08:00
|
|
|
return RegisterClassEx(&wcex);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL InitInstance(HINSTANCE hInstance, DWORD nAdmin, RECT* rc)
|
|
|
|
{
|
|
|
|
hIns = hInstance;
|
2016-01-05 23:01:17 +08:00
|
|
|
LPCWSTR name = (nAdmin) ? ClassNameAdmin : ClassName;
|
2015-04-02 22:27:58 +08:00
|
|
|
hMainWnd = CreateWindow(ClassName, name, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
|
|
|
|
rc->left, rc->top, rc->right - rc->left, rc->bottom - rc->top, NULL, NULL, hInstance, 0);
|
|
|
|
if (!hMainWnd)
|
|
|
|
return FALSE;
|
|
|
|
ShowWindow(hMainWnd, SW_SHOWNORMAL);
|
|
|
|
UpdateWindow(hMainWnd);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD SaveProcessProfile(DWORD pid); // ProfileManager.cpp
|
|
|
|
|
|
|
|
BOOL CALLBACK OptionDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
switch (uMsg)
|
|
|
|
{
|
|
|
|
case WM_INITDIALOG:
|
|
|
|
{
|
|
|
|
SetWindowText(GetDlgItem(hDlg, IDC_EDIT1), std::to_wstring((long long)split_time).c_str());
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
case WM_COMMAND:
|
|
|
|
{
|
|
|
|
DWORD wmId = LOWORD(wParam);
|
|
|
|
DWORD wmEvent = HIWORD(wParam);
|
|
|
|
switch (wmId)
|
|
|
|
{
|
|
|
|
case IDOK:
|
|
|
|
{
|
|
|
|
WCHAR str[128];
|
|
|
|
GetWindowText(GetDlgItem(hDlg, IDC_EDIT1), str, 0x80);
|
|
|
|
DWORD st = std::stoul(str);
|
|
|
|
split_time = st > 100 ? st : 100;
|
2018-07-18 05:01:56 +08:00
|
|
|
man->SetSplitInterval(split_time);
|
2015-04-02 22:27:58 +08:00
|
|
|
}
|
|
|
|
case IDCANCEL:
|
|
|
|
EndDialog(hDlg, 0);
|
|
|
|
hOptionDlg = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL CALLBACK ProcessDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
switch (uMsg)
|
|
|
|
{
|
|
|
|
case WM_INITDIALOG:
|
|
|
|
{
|
|
|
|
pswnd = new ProcessWindow(hDlg);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
case WM_COMMAND:
|
|
|
|
{
|
|
|
|
DWORD wmId, wmEvent;
|
|
|
|
wmId = LOWORD(wParam);
|
|
|
|
wmEvent = HIWORD(wParam);
|
|
|
|
switch (wmId)
|
|
|
|
{
|
|
|
|
case WM_DESTROY:
|
|
|
|
case IDOK:
|
|
|
|
EndDialog(hDlg, NULL);
|
|
|
|
hProcDlg = NULL;
|
|
|
|
delete pswnd;
|
|
|
|
pswnd = NULL;
|
|
|
|
break;
|
|
|
|
case IDC_BUTTON1:
|
|
|
|
pswnd->RefreshProcess();
|
|
|
|
break;
|
|
|
|
case IDC_BUTTON2:
|
|
|
|
pswnd->AttachProcess();
|
|
|
|
break;
|
|
|
|
case IDC_BUTTON3:
|
|
|
|
pswnd->DetachProcess();
|
|
|
|
break;
|
|
|
|
case IDC_BUTTON5:
|
2016-01-05 23:01:17 +08:00
|
|
|
pswnd->CreateProfileForSelectedProcess();
|
2015-04-02 22:27:58 +08:00
|
|
|
break;
|
|
|
|
case IDC_BUTTON6:
|
2016-01-05 23:01:17 +08:00
|
|
|
pswnd->DeleteProfileForSelectedProcess();
|
2015-04-02 22:27:58 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
2016-01-05 23:01:17 +08:00
|
|
|
|
2015-04-02 22:27:58 +08:00
|
|
|
case WM_NOTIFY:
|
|
|
|
{
|
|
|
|
LPNMHDR dr = (LPNMHDR)lParam;
|
|
|
|
switch (dr->code)
|
|
|
|
{
|
|
|
|
case LVN_ITEMCHANGED:
|
|
|
|
if (dr->idFrom == IDC_LIST1)
|
|
|
|
{
|
|
|
|
NMLISTVIEW *nmlv = (LPNMLISTVIEW)lParam;
|
|
|
|
if (nmlv->uNewState & LVIS_SELECTED)
|
|
|
|
pswnd->RefreshThread(nmlv->iItem);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CALLBACK EditProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
|
|
|
|
switch (message)
|
|
|
|
{
|
|
|
|
case WM_CHAR: //Filter user input.
|
2016-01-05 23:01:17 +08:00
|
|
|
if (GetKeyState(VK_CONTROL) & 0x8000)
|
|
|
|
{
|
|
|
|
if (wParam == 1)
|
2015-04-02 22:27:58 +08:00
|
|
|
{
|
2016-01-05 23:01:17 +08:00
|
|
|
Edit_SetSel(hwndEdit, 0, -1);
|
|
|
|
SendMessage(hwndEdit, WM_COPY, 0, 0);
|
2015-04-02 22:27:58 +08:00
|
|
|
}
|
2016-01-05 23:01:17 +08:00
|
|
|
}
|
|
|
|
return 0;
|
2015-04-02 22:27:58 +08:00
|
|
|
case WM_LBUTTONUP:
|
2016-01-05 23:01:17 +08:00
|
|
|
if (hwndEdit)
|
|
|
|
SendMessage(hwndEdit, WM_COPY, 0, 0);
|
2015-04-02 22:27:58 +08:00
|
|
|
default:
|
2016-01-05 23:01:17 +08:00
|
|
|
{
|
|
|
|
return proc(hWnd, message, wParam, lParam);
|
|
|
|
}
|
2015-04-02 22:27:58 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CALLBACK EditCmdProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
switch (message)
|
|
|
|
{
|
|
|
|
case WM_KEYDOWN:
|
|
|
|
if (wParam == VK_UP)
|
|
|
|
{
|
|
|
|
SetWindowText(hWnd, last_cmd);
|
|
|
|
SetFocus(hWnd);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_CHAR:
|
|
|
|
if (wParam == VK_RETURN)
|
|
|
|
{
|
|
|
|
DWORD s = 0, pid = 0;
|
|
|
|
WCHAR str[32];
|
|
|
|
if (GetWindowTextLength(hWnd) == 0)
|
|
|
|
break;
|
|
|
|
GetWindowText(hWnd, last_cmd, CMD_SIZE);
|
|
|
|
//IthBreak();
|
|
|
|
if (GetWindowText(hwndProcessComboBox, str, 32))
|
|
|
|
pid = std::stoul(str);
|
|
|
|
ProcessCommand(last_cmd, pid);
|
|
|
|
Edit_SetSel(hWnd, 0, -1);
|
|
|
|
Edit_ReplaceSel(hWnd, &s);
|
|
|
|
SetFocus(hWnd);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return CallWindowProc(proccmd, hWnd, message, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CreateButtons(HWND hWnd)
|
|
|
|
{
|
2016-12-15 22:25:38 +08:00
|
|
|
hwndProcess = CreateWindow(L"Button", L"Process", WS_CHILD | WS_VISIBLE,
|
2015-04-02 22:27:58 +08:00
|
|
|
0, 0, 0, 0, hWnd, 0, hIns, NULL);
|
2016-12-15 22:25:38 +08:00
|
|
|
hwndOption = CreateWindow(L"Button", L"Option", WS_CHILD | WS_VISIBLE,
|
2015-04-02 22:27:58 +08:00
|
|
|
0, 0, 0, 0, hWnd, 0, hIns, NULL);
|
2016-12-15 22:25:38 +08:00
|
|
|
hwndClear = CreateWindow(L"Button", L"Clear", WS_CHILD | WS_VISIBLE,
|
2015-04-02 22:27:58 +08:00
|
|
|
0, 0, 0, 0, hWnd, 0, hIns, NULL);
|
2016-12-15 22:25:38 +08:00
|
|
|
hwndSave = CreateWindow(L"Button", L"Save", WS_CHILD | WS_VISIBLE,
|
2015-04-02 22:27:58 +08:00
|
|
|
0, 0, 0, 0, hWnd, 0, hIns, NULL);
|
2018-07-13 23:47:16 +08:00
|
|
|
hwndExtensions = CreateWindow(L"Button", L"Extensions", WS_CHILD | WS_VISIBLE,
|
2015-04-02 22:27:58 +08:00
|
|
|
0, 0, 0, 0, hWnd, 0, hIns, NULL);
|
2016-12-15 22:25:38 +08:00
|
|
|
hwndRemoveHook = CreateWindow(L"Button", L"Unhook", WS_CHILD | WS_VISIBLE,
|
2015-04-02 22:27:58 +08:00
|
|
|
0, 0, 0, 0, hWnd, 0, hIns, NULL);
|
2016-12-15 22:25:38 +08:00
|
|
|
hwndTop = CreateWindow(L"Button", L"Top", WS_CHILD | WS_VISIBLE | BS_PUSHLIKE | BS_CHECKBOX,
|
2015-04-02 22:27:58 +08:00
|
|
|
0, 0, 0, 0, hWnd, 0, hIns, NULL);
|
|
|
|
hwndProcessComboBox = CreateWindow(L"ComboBox", NULL,
|
|
|
|
WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST |
|
|
|
|
CBS_SORT | WS_VSCROLL | WS_TABSTOP,
|
|
|
|
0, 0, 0, 0, hWnd, 0, hIns, NULL);
|
|
|
|
hwndCmd = CreateWindowEx(WS_EX_CLIENTEDGE, L"Edit", NULL,
|
2016-01-05 23:01:17 +08:00
|
|
|
WS_CHILD | WS_VISIBLE | ES_NOHIDESEL | ES_LEFT | ES_AUTOHSCROLL,
|
2015-04-02 22:27:58 +08:00
|
|
|
0, 0, 0, 0, hWnd, 0, hIns, NULL);
|
|
|
|
hwndEdit = CreateWindowEx(WS_EX_CLIENTEDGE, L"Edit", NULL,
|
2016-01-05 23:01:17 +08:00
|
|
|
WS_CHILD | WS_VISIBLE | ES_NOHIDESEL | WS_VSCROLL |
|
2015-04-02 22:27:58 +08:00
|
|
|
ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,
|
|
|
|
0, 0, 0, 0, hWnd, 0, hIns, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClickButton(HWND hWnd, HWND h)
|
|
|
|
{
|
|
|
|
if (h == hwndProcess)
|
|
|
|
{
|
|
|
|
if (hProcDlg)
|
|
|
|
SetForegroundWindow(hProcDlg);
|
|
|
|
else
|
|
|
|
hProcDlg = CreateDialog(hIns, (LPWSTR)IDD_DIALOG2, 0, ProcessDlgProc);
|
|
|
|
}
|
|
|
|
else if (h == hwndOption)
|
|
|
|
{
|
|
|
|
if (hOptionDlg)
|
|
|
|
SetForegroundWindow(hOptionDlg);
|
|
|
|
else
|
|
|
|
hOptionDlg = CreateDialog(hIns, (LPWSTR)IDD_DIALOG4, 0, OptionDlgProc);
|
|
|
|
}
|
|
|
|
else if (h == hwndClear)
|
|
|
|
{
|
2018-06-03 02:29:32 +08:00
|
|
|
man->ClearCurrent();
|
2015-04-02 22:27:58 +08:00
|
|
|
}
|
|
|
|
else if (h == hwndTop)
|
|
|
|
{
|
2016-01-05 23:01:17 +08:00
|
|
|
if (Button_GetCheck(h) == BST_CHECKED)
|
2015-04-02 22:27:58 +08:00
|
|
|
{
|
|
|
|
Button_SetCheck(h, BST_UNCHECKED);
|
|
|
|
SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
|
|
|
|
if (hProcDlg)
|
|
|
|
SetWindowPos(hProcDlg, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
|
|
|
|
if (hOptionDlg)
|
|
|
|
SetWindowPos(hOptionDlg, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Button_SetCheck(h, BST_CHECKED);
|
|
|
|
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
|
|
|
|
if (hProcDlg)
|
|
|
|
SetWindowPos(hProcDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
|
|
|
|
if (hOptionDlg)
|
|
|
|
SetWindowPos(hOptionDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (h == hwndSave)
|
|
|
|
{
|
|
|
|
WCHAR str[32];
|
|
|
|
if (GetWindowText(hwndProcessComboBox, str, 32))
|
|
|
|
{
|
|
|
|
DWORD pid = std::stoul(str);
|
|
|
|
SaveProcessProfile(pid);
|
|
|
|
}
|
2016-01-05 23:01:17 +08:00
|
|
|
pfman->SaveProfiles();
|
2015-04-02 22:27:58 +08:00
|
|
|
}
|
2018-07-13 23:47:16 +08:00
|
|
|
else if (h == hwndExtensions)
|
|
|
|
{
|
|
|
|
man->AddConsoleOutput(L"GUI for managing your extensions coming soon. Please do it manually for now.");
|
|
|
|
}
|
2015-04-02 22:27:58 +08:00
|
|
|
else if (h == hwndRemoveHook)
|
|
|
|
{
|
|
|
|
WCHAR str[32];
|
|
|
|
if (GetWindowText(hwndCombo, str, 32))
|
|
|
|
{
|
|
|
|
std::wstring entry(str);
|
|
|
|
std::size_t i;
|
|
|
|
DWORD threadNumber = std::stoul(entry, &i, 16);
|
|
|
|
entry = entry.substr(i + 1);
|
|
|
|
DWORD pid = std::stoul(entry, &i);
|
|
|
|
entry = entry.substr(i + 1);
|
|
|
|
DWORD addr = std::stoul(entry, NULL, 16);
|
|
|
|
if (threadNumber != 0)
|
2018-07-13 23:47:16 +08:00
|
|
|
RemoveHook(pid, addr);
|
2015-04-02 22:27:58 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-19 04:18:43 +08:00
|
|
|
void ThreadOutput(TextThread* thread, std::wstring output)
|
2015-04-02 22:27:58 +08:00
|
|
|
{
|
2018-07-19 04:18:43 +08:00
|
|
|
if (thread->Status() & CURRENT_SELECT) texts->AddText(output, false);
|
2015-04-02 22:27:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool GetHookParam(DWORD pid, DWORD hook_addr, HookParam& hp)
|
|
|
|
{
|
|
|
|
if (!pid)
|
|
|
|
return false;
|
2018-07-18 07:18:36 +08:00
|
|
|
hp = man->GetHook(pid, hook_addr).hp;
|
|
|
|
return true;
|
2015-04-02 22:27:58 +08:00
|
|
|
}
|
|
|
|
|
2018-07-19 04:18:43 +08:00
|
|
|
std::wstring CreateEntryWithLink(ThreadParameter tp, std::wstring& entry)
|
2016-01-05 23:01:17 +08:00
|
|
|
{
|
|
|
|
std::wstring entryWithLink = entry;
|
2018-07-19 04:18:43 +08:00
|
|
|
if (tp.pid == 0)
|
2015-04-02 22:27:58 +08:00
|
|
|
entryWithLink += L"ConsoleOutput";
|
|
|
|
HookParam hp = {};
|
2018-07-19 04:18:43 +08:00
|
|
|
if (GetHookParam(tp.pid, tp.hook, hp))
|
|
|
|
entryWithLink += L" (" + GetCode(hp, tp.hook) + L")";
|
2016-01-05 23:01:17 +08:00
|
|
|
return entryWithLink;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AddToCombo(TextThread& thread, bool replace)
|
|
|
|
{
|
2018-07-19 04:18:43 +08:00
|
|
|
std::wstring entry = GetEntryString(&thread);
|
|
|
|
std::wstring entryWithLink = CreateEntryWithLink(thread.GetThreadParameter(), entry);
|
2016-01-05 23:01:17 +08:00
|
|
|
int i = ComboBox_FindString(hwndCombo, -1, entry.c_str());
|
2015-04-02 22:27:58 +08:00
|
|
|
if (replace)
|
|
|
|
{
|
|
|
|
int sel = ComboBox_GetCurSel(hwndCombo);
|
|
|
|
if (i != CB_ERR)
|
|
|
|
ComboBox_DeleteString(hwndCombo, i);
|
|
|
|
ComboBox_AddString(hwndCombo, entryWithLink.c_str());
|
|
|
|
ComboBox_SetCurSel(hwndCombo, sel);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (i == CB_ERR)
|
|
|
|
ComboBox_AddString(hwndCombo, entryWithLink.c_str());
|
|
|
|
// Why set current selection to 0 when the new thread is selected?
|
|
|
|
if (thread.Status() & CURRENT_SELECT)
|
|
|
|
ComboBox_SetCurSel(hwndCombo, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void RemoveFromCombo(TextThread* thread)
|
|
|
|
{
|
2018-07-19 04:18:43 +08:00
|
|
|
std::wstring entry = GetEntryString(thread);
|
|
|
|
if (thread->GetThreadParameter().pid == 0)
|
|
|
|
entry += L"ConsoleOutput";
|
|
|
|
int i = ComboBox_FindString(hwndCombo, 0, entry.c_str());
|
2015-04-02 22:27:58 +08:00
|
|
|
if (i != CB_ERR)
|
|
|
|
{
|
|
|
|
if (ComboBox_DeleteString(hwndCombo, i) == CB_ERR)
|
|
|
|
ConsoleOutput(ErrorDeleteCombo);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-19 04:18:43 +08:00
|
|
|
DWORD SetEditText(LPCWSTR wc)
|
2015-04-02 22:27:58 +08:00
|
|
|
{
|
|
|
|
DWORD line;
|
|
|
|
Edit_SetText(hwndEdit, wc);
|
|
|
|
line = Edit_GetLineCount(hwndEdit);
|
|
|
|
SendMessage(hwndEdit, EM_LINESCROLL, 0, line);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD ThreadReset(TextThread* thread)
|
|
|
|
{
|
|
|
|
texts->ClearBuffer();
|
2018-07-19 04:18:43 +08:00
|
|
|
man->SetCurrent(thread);;
|
2018-07-12 08:18:04 +08:00
|
|
|
|
2018-07-19 04:18:43 +08:00
|
|
|
std::wstring text = thread->GetStore();
|
|
|
|
SetEditText(text.c_str());
|
2018-07-12 08:18:04 +08:00
|
|
|
|
2015-04-02 22:27:58 +08:00
|
|
|
WCHAR buffer[16];
|
|
|
|
std::swprintf(buffer, L"%04X", thread->Number());
|
|
|
|
DWORD tmp = ComboBox_FindString(hwndCombo, 0, buffer);
|
|
|
|
if (tmp != CB_ERR)
|
|
|
|
ComboBox_SetCurSel(hwndCombo, tmp);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD AddRemoveLink(TextThread* thread)
|
|
|
|
{
|
|
|
|
AddToCombo(*thread, true);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-01-05 23:01:17 +08:00
|
|
|
bool IsUnicodeHook(const ProcessRecord& pr, DWORD hook);
|
|
|
|
|
|
|
|
DWORD ThreadCreate(TextThread* thread)
|
|
|
|
{
|
2018-07-19 04:18:43 +08:00
|
|
|
thread->RegisterOutputCallBack(ThreadOutput);
|
2018-06-10 16:53:14 +08:00
|
|
|
//thread->RegisterFilterCallBack(ThreadFilter, 0);
|
2016-01-05 23:01:17 +08:00
|
|
|
AddToCombo(*thread, false);
|
2018-07-19 04:18:43 +08:00
|
|
|
auto tp = thread->GetThreadParameter();
|
|
|
|
auto pr = man->GetProcessRecord(tp.pid);
|
2016-01-05 23:01:17 +08:00
|
|
|
if (pr == NULL)
|
|
|
|
return 0;
|
2018-07-19 04:18:43 +08:00
|
|
|
if (IsUnicodeHook(*pr, tp.hook))
|
2016-01-05 23:01:17 +08:00
|
|
|
thread->Status() |= USING_UNICODE;
|
2018-07-19 04:18:43 +08:00
|
|
|
auto pf = pfman->GetProfile(tp.pid);
|
2016-01-05 23:01:17 +08:00
|
|
|
if (!pf)
|
|
|
|
return 0;
|
2018-07-19 04:18:43 +08:00
|
|
|
const std::wstring& hook_name = GetHookNameByAddress(*pr, thread->GetThreadParameter().hook);
|
|
|
|
auto thread_profile = pf->FindThread(&thread->GetThreadParameter(), hook_name);
|
2016-01-05 23:01:17 +08:00
|
|
|
if (thread_profile != pf->Threads().end())
|
|
|
|
{
|
|
|
|
(*thread_profile)->HookManagerIndex() = thread->Number();
|
|
|
|
auto thread_index = thread_profile - pf->Threads().begin();
|
|
|
|
if (pf->IsThreadSelected(thread_profile))
|
|
|
|
ThreadReset(thread);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-04-02 22:27:58 +08:00
|
|
|
bool IsUnicodeHook(const ProcessRecord& pr, DWORD hook)
|
|
|
|
{
|
|
|
|
bool res = false;
|
|
|
|
WaitForSingleObject(pr.hookman_mutex, 0);
|
2018-07-18 07:18:36 +08:00
|
|
|
auto hooks = (const OldHook*)pr.hookman_map;
|
2015-04-02 22:27:58 +08:00
|
|
|
for (DWORD i = 0; i < MAX_HOOK; i++)
|
|
|
|
{
|
|
|
|
if (hooks[i].Address() == hook)
|
|
|
|
{
|
|
|
|
res = hooks[i].Type() & USING_UNICODE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ReleaseMutex(pr.hookman_mutex);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD ThreadRemove(TextThread* thread)
|
|
|
|
{
|
|
|
|
RemoveFromCombo(thread);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-07-13 23:47:16 +08:00
|
|
|
DWORD RegisterProcess(DWORD pid)
|
2015-04-02 22:27:58 +08:00
|
|
|
{
|
|
|
|
auto path = GetProcessPath(pid);
|
|
|
|
if (!path.empty())
|
|
|
|
{
|
|
|
|
WCHAR str[MAX_PATH];
|
|
|
|
std::swprintf(str, L"%04d:%s", pid, path.substr(path.rfind(L'\\') + 1).c_str());
|
|
|
|
ComboBox_AddString(hwndProcessComboBox, str);
|
|
|
|
if (ComboBox_GetCount(hwndProcessComboBox) == 1)
|
|
|
|
ComboBox_SetCurSel(hwndProcessComboBox, 0);
|
|
|
|
}
|
2018-07-13 23:47:16 +08:00
|
|
|
Profile* pf = pfman->GetProfile(pid);
|
|
|
|
if (pf)
|
|
|
|
{
|
|
|
|
for (auto i = pf->Hooks().begin(); i != pf->Hooks().end(); ++i)
|
|
|
|
{
|
|
|
|
InsertHook(pid, &i->get()->HP(), toMultiByteString(i->get()->Name()));
|
|
|
|
}
|
|
|
|
}
|
2015-04-02 22:27:58 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD RemoveProcessList(DWORD pid)
|
|
|
|
{
|
|
|
|
WCHAR str[MAX_PATH];
|
|
|
|
std::swprintf(str, L"%04d", pid);
|
|
|
|
DWORD i = ComboBox_FindString(hwndProcessComboBox, 0, str);
|
|
|
|
DWORD j = ComboBox_GetCurSel(hwndProcessComboBox);
|
|
|
|
if (i != CB_ERR)
|
|
|
|
{
|
|
|
|
DWORD k = ComboBox_DeleteString(hwndProcessComboBox, i);
|
|
|
|
if (i == j)
|
|
|
|
ComboBox_SetCurSel(hwndProcessComboBox, 0);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
switch (message)
|
|
|
|
{
|
2016-01-05 23:01:17 +08:00
|
|
|
case WM_CREATE:
|
|
|
|
CreateButtons(hWnd);
|
|
|
|
// Add text to the window.
|
|
|
|
Edit_LimitText(hwndEdit, -1);
|
|
|
|
SendMessage(hwndEdit, WM_INPUTLANGCHANGEREQUEST, 0, 0x411);
|
|
|
|
proc = (WNDPROC)SetWindowLong(hwndEdit, GWL_WNDPROC, (LONG)EditProc);
|
|
|
|
proccmd = (WNDPROC)SetWindowLong(hwndCmd, GWL_WNDPROC, (LONG)EditCmdProc);
|
|
|
|
hwndCombo = CreateWindow(L"ComboBox", NULL,
|
|
|
|
WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST |
|
|
|
|
CBS_SORT | WS_VSCROLL | WS_TABSTOP,
|
|
|
|
0, 0, 0, 0, hWnd, 0, hIns, NULL);
|
|
|
|
{
|
|
|
|
HDC hDC = GetDC(hWnd);
|
|
|
|
int nHeight = -MulDiv(12, GetDeviceCaps(hDC, LOGPIXELSY), 72);
|
|
|
|
ReleaseDC(hWnd, hDC);
|
|
|
|
HFONT hf = CreateFont(nHeight, 0, 0, 0, FW_LIGHT, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET,
|
|
|
|
OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
|
|
|
|
L"MS Gothic");
|
|
|
|
hWhiteBrush = GetStockBrush(WHITE_BRUSH);
|
|
|
|
SendMessage(hwndCmd, WM_SETFONT, (WPARAM)hf, 0);
|
|
|
|
SendMessage(hwndEdit, WM_SETFONT, (WPARAM)hf, 0);
|
|
|
|
SendMessage(hwndCombo, WM_SETFONT, (WPARAM)hf, 0);
|
|
|
|
SendMessage(hwndProcessComboBox, WM_SETFONT, (WPARAM)hf, 0);
|
|
|
|
texts = new TextBuffer(hwndEdit);
|
|
|
|
man->RegisterThreadCreateCallback(ThreadCreate);
|
|
|
|
man->RegisterThreadRemoveCallback(ThreadRemove);
|
|
|
|
man->RegisterThreadResetCallback(ThreadReset);
|
|
|
|
TextThread* console = man->FindSingle(0);
|
2018-07-19 04:18:43 +08:00
|
|
|
console->RegisterOutputCallBack(ThreadOutput);
|
2016-01-05 23:01:17 +08:00
|
|
|
AddToCombo(*console, false);
|
2018-07-13 23:47:16 +08:00
|
|
|
man->RegisterProcessAttachCallback(RegisterProcess);
|
2016-01-05 23:01:17 +08:00
|
|
|
man->RegisterProcessDetachCallback(RemoveProcessList);
|
2018-05-31 16:44:33 +08:00
|
|
|
//man->RegisterProcessNewHookCallback(RefreshProfileOnNewHook); Artikash 5/30/2018 TODO: Finish implementing this.
|
2016-01-05 23:01:17 +08:00
|
|
|
man->RegisterAddRemoveLinkCallback(AddRemoveLink);
|
2018-07-18 05:01:56 +08:00
|
|
|
OpenHost();
|
2015-04-02 22:27:58 +08:00
|
|
|
{
|
2018-07-13 23:47:16 +08:00
|
|
|
static const WCHAR program_name[] = L"NextHooker beta v";
|
2016-01-05 23:01:17 +08:00
|
|
|
//static const WCHAR program_version[] = L"3.0";
|
|
|
|
static WCHAR version_info[256];
|
2018-07-13 23:47:16 +08:00
|
|
|
std::swprintf(version_info, L"%s%s (%s)", program_name, program_version, build_date);
|
2016-01-05 23:01:17 +08:00
|
|
|
man->AddConsoleOutput(version_info);
|
|
|
|
man->AddConsoleOutput(InitMessage);
|
2015-04-02 22:27:58 +08:00
|
|
|
}
|
|
|
|
|
2016-01-05 23:01:17 +08:00
|
|
|
if (background == 0)
|
|
|
|
man->AddConsoleOutput(BackgroundMsg);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
case WM_COMMAND:
|
|
|
|
{
|
|
|
|
DWORD wmId, wmEvent, dwId;
|
|
|
|
wmId = LOWORD(wParam);
|
|
|
|
wmEvent = HIWORD(wParam);
|
|
|
|
switch (wmEvent)
|
|
|
|
{
|
|
|
|
case EN_VSCROLL:
|
|
|
|
{
|
|
|
|
SCROLLBARINFO info = { sizeof(info) };
|
|
|
|
GetScrollBarInfo(hwndEdit, OBJID_VSCROLL, &info);
|
|
|
|
InvalidateRect(hwndEdit, 0, 1);
|
|
|
|
ValidateRect(hwndEdit, &info.rcScrollBar);
|
|
|
|
RedrawWindow(hwndEdit, 0, 0, RDW_ERASE);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CBN_SELENDOK:
|
|
|
|
{
|
|
|
|
if ((HWND)lParam == hwndProcessComboBox)
|
|
|
|
return 0;
|
|
|
|
dwId = ComboBox_GetCurSel(hwndCombo);
|
|
|
|
int len = ComboBox_GetLBTextLen(hwndCombo, dwId);
|
|
|
|
if (len > 0)
|
2015-04-02 22:27:58 +08:00
|
|
|
{
|
2016-01-05 23:01:17 +08:00
|
|
|
LPWSTR pwcEntry = new WCHAR[len + 1];
|
|
|
|
len = ComboBox_GetLBText(hwndCombo, dwId, pwcEntry);
|
|
|
|
DWORD num = std::stoul(pwcEntry, NULL, 16);
|
|
|
|
man->SelectCurrent(num);
|
|
|
|
delete[] pwcEntry;
|
2015-04-02 22:27:58 +08:00
|
|
|
}
|
2016-01-05 23:01:17 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
case BN_CLICKED:
|
|
|
|
ClickButton(hWnd, (HWND)lParam);
|
2015-04-02 22:27:58 +08:00
|
|
|
break;
|
|
|
|
default:
|
2016-01-05 23:01:17 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case WM_SETFOCUS:
|
|
|
|
SetFocus(hwndEdit);
|
|
|
|
return 0;
|
|
|
|
case WM_SIZE:
|
|
|
|
{
|
|
|
|
WORD width = LOWORD(lParam);
|
|
|
|
WORD height = HIWORD(lParam);
|
|
|
|
DWORD l = width / 7;
|
|
|
|
WORD h = HIWORD(GetDialogBaseUnits()); // height of the system font
|
|
|
|
h = h + (h / 2);
|
|
|
|
HDC hDC = GetDC(hWnd);
|
|
|
|
RECT rc;
|
|
|
|
GetClientRect(hWnd, &rc);
|
|
|
|
FillRect(hDC, &rc, hWhiteBrush);
|
|
|
|
ReleaseDC(hWnd, hDC);
|
|
|
|
MoveWindow(hwndProcess, 0, 0, l, h, TRUE);
|
|
|
|
MoveWindow(hwndOption, l * 1, 0, l, h, TRUE);
|
|
|
|
MoveWindow(hwndTop, l * 2, 0, l, h, TRUE);
|
|
|
|
MoveWindow(hwndClear, l * 3, 0, l, h, TRUE);
|
2018-07-13 23:47:16 +08:00
|
|
|
MoveWindow(hwndExtensions, l * 4, 0, l, h, TRUE);
|
2016-01-05 23:01:17 +08:00
|
|
|
MoveWindow(hwndRemoveHook, l * 5, 0, l, h, TRUE);
|
|
|
|
MoveWindow(hwndSave, l * 6, 0, width - 6 * l, h, TRUE);
|
|
|
|
l *= 2;
|
|
|
|
MoveWindow(hwndProcessComboBox, 0, h, l, 200, TRUE);
|
|
|
|
MoveWindow(hwndCmd, l, h, width - l, h, TRUE);
|
|
|
|
MoveWindow(hwndCombo, 0, h * 2, width, 200, TRUE);
|
|
|
|
h *= 3;
|
|
|
|
MoveWindow(hwndEdit, 0, h, width, height - h, TRUE);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
case WM_DESTROY:
|
|
|
|
man->RegisterThreadCreateCallback(0);
|
|
|
|
man->RegisterThreadRemoveCallback(0);
|
|
|
|
man->RegisterThreadResetCallback(0);
|
|
|
|
man->RegisterProcessAttachCallback(0);
|
|
|
|
man->RegisterProcessDetachCallback(0);
|
|
|
|
//delete texts;
|
|
|
|
SaveSettings();
|
|
|
|
PostQuitMessage(0);
|
|
|
|
return 0;
|
|
|
|
default:
|
|
|
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
2015-04-02 22:27:58 +08:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|