NTSTATUS GetExeImageSize(LPWSTR ExeFullPath, PULONG SizeOfImage) { ULONG Size; NTSTATUS Status; NtFileDisk file; IMAGE_DOS_HEADER DosHeader; IMAGE_NT_HEADERS NtHeader; PIMAGE_OPTIONAL_HEADER OptionalHeader; PIMAGE_SECTION_HEADER SectionHeader; Status = file.Open(ExeFullPath); if (!NT_SUCCESS(Status)) return Status; Status = file.Read(&DosHeader, sizeof(DosHeader)); if (!NT_SUCCESS(Status)) return Status; if (DosHeader.e_magic != IMAGE_DOS_SIGNATURE) return STATUS_INVALID_IMAGE_WIN_32; Status = file.Seek(DosHeader.e_lfanew, FILE_BEGIN); if (!NT_SUCCESS(Status)) return Status; Status = file.Read(&NtHeader, sizeof(NtHeader) - sizeof(NtHeader.OptionalHeader)); if (!NT_SUCCESS(Status)) return Status; if (NtHeader.Signature != IMAGE_NT_SIGNATURE) return STATUS_INVALID_IMAGE_WIN_32; if (NtHeader.FileHeader.SizeOfOptionalHeader > FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, SizeOfImage) + RTL_FIELD_SIZE(IMAGE_OPTIONAL_HEADER, SizeOfImage)) { OptionalHeader = (PIMAGE_OPTIONAL_HEADER)AllocStack(NtHeader.FileHeader.SizeOfOptionalHeader); Status = file.Read(OptionalHeader, NtHeader.FileHeader.SizeOfOptionalHeader); if (!NT_SUCCESS(Status)) return Status; *SizeOfImage = OptionalHeader->SizeOfImage; return STATUS_SUCCESS; } SectionHeader = (PIMAGE_SECTION_HEADER)AllocStack(NtHeader.FileHeader.NumberOfSections * sizeof(*SectionHeader)); Status = file.Read(SectionHeader, NtHeader.FileHeader.NumberOfSections * sizeof(*SectionHeader)); if (!NT_SUCCESS(Status)) return Status; Size = 0; for (ULONG NumberOfSections = NtHeader.FileHeader.NumberOfSections; NumberOfSections; --NumberOfSections) { Size += SectionHeader->Misc.VirtualSize; ++SectionHeader; } Size += ROUND_UP(file.GetCurrentPos(), MEMORY_PAGE_SIZE); *SizeOfImage = Size; return STATUS_SUCCESS; }
Int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) { ULONG CodePage, Length; PWCHAR pWText, pWCaption; Length = StrLengthA(lpText); pWText = (PWCHAR)AllocStack(Length * sizeof(*pWText)); if (IsShiftJISString(lpText, -1)) CodePage = CP_SHIFTJIS; else CodePage = CP_GB2312; MultiByteToWideChar(CodePage, 0, lpText, -1, pWText, Length); Length = StrLengthA(lpCaption); pWCaption = (PWCHAR)AllocStack(Length * sizeof(*pWCaption)); if (IsShiftJISString(lpCaption, -1)) CodePage = CP_SHIFTJIS; else CodePage = CP_GB2312; MultiByteToWideChar(CodePage, 0, lpCaption, -1, pWCaption, Length); return MessageBoxW(hWnd, pWText, pWCaption, uType); }
HWND WINAPI CreateWindowExCenterA(ULONG dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, ULONG dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) { HWND Window; RECT rcWordArea; ULONG Length; PWSTR pszClassName, pszWindowName; Length = StrLengthA(lpClassName) + 1; pszClassName = (PWSTR)AllocStack(Length * sizeof(WCHAR)); AnsiToUnicode(pszClassName, Length, lpClassName, Length); Length = StrLengthA(lpWindowName) + 1; pszWindowName = (PWSTR)AllocStack(Length * sizeof(WCHAR)); AnsiToUnicode(pszWindowName, Length, lpWindowName, Length); if (SystemParametersInfoW(SPI_GETWORKAREA, 0, &rcWordArea, 0)) { X = ((rcWordArea.right - rcWordArea.left) - nWidth) / 2; Y = ((rcWordArea.bottom - rcWordArea.top) - nHeight) / 2; } Window = CreateWindowExW(dwExStyle, pszClassName, pszWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); ChangeMainWindowProc(Window); return Window; }
LONG CED6AsDecompiler::DumpCrafts(ED6_ACTION_SCRIPT_INFO *pAsInfo, CFileDisk &file, LPSTR Buffer) { LONG Status; PULONG pCraftIndex; ED6_AS_CRAFT_INFO *pCraft; pCraftIndex = (PULONG)AllocStack(pAsInfo->CraftCount * sizeof(*pCraft)); for (ULONG Index = 0, Count = pAsInfo->CraftCount; Count; --Count) { pCraftIndex[Index] = Index; ++Index; } for (ULONG i = pAsInfo->CraftCount; i; --i) { for (ULONG j = 0; j != i - 1; ++j) { if (pAsInfo->pCraftInfo[pCraftIndex[j]].Offset > pAsInfo->pCraftInfo[pCraftIndex[j + 1]].Offset) Swap(pCraftIndex[j], pCraftIndex[j + 1]); } } pCraft = pAsInfo->pCraftInfo; for (ULONG Count = pAsInfo->CraftCount; Count; --Count) { Status = DumpOneCraft(pAsInfo, &pCraft[*pCraftIndex++], file, Buffer); AS_IF_FAIL_BREAK(Status); } return Status; }
HWND WINAPI MyCreateWindowExA(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) { PWCHAR pszClass, pszWindow; ULONG Length, CP; Length = StrLengthA(lpClassName); pszClass = (PWCHAR)AllocStack(Length * 2); CP = CP_SHIFTJIS; MultiByteToWideChar(CP, 0, lpClassName, Length + 1, pszClass, Length * 2); Length = StrLengthA(lpWindowName); pszWindow = (PWCHAR)AllocStack(Length * 2); MultiByteToWideChar(CP, 0, lpWindowName, Length + 1, pszWindow, Length * 2); return CreateWindowExW(dwExStyle, pszClass, pszWindow, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); }
void Stackable::AllocateDataStacks(StabEnt *s) { if (s->isDeleted || s->refType == TypedValue::REF_INSTANCE) return; if (s->refType == TypedValue::REF_STACK) { long nobj=1; for (short i=1; i<=sym->indirection; i++) { nobj *= sym->size[i]; } switch (s->type) { case TypedValue::S_BOOL: case TypedValue::S_BYTE: case TypedValue::S_SHORT: case TypedValue::S_INT: case TypedValue::S_LONG: case TypedValue::S_NOTE: case TypedValue::S_CTRL: case TypedValue::S_PROG: case TypedValue::S_BEND: case TypedValue::S_SYSC: case TypedValue::S_SYSX: case TypedValue::S_MESSAGE: case TypedValue::S_JOY: case TypedValue::S_FLOAT: s->SetStackReference(sym, AllocStack(s->context, s->type, nobj)); break; case TypedValue::S_STRUCT: { s->size[0] = 0; s->SetStackReference(sym, AllocStack(s->context, TypedValue::S_STRUCT, nobj)); for (StabEnt *p=s->children; p!=nullptr; p=p->sibling) { AllocateDataStacks(p); } EndStructureAllocation(sym); break; } } } }
BOOL WINAPI MySetWindowTextA(HWND hWnd, LPCSTR lpString) { ULONG Length, CP; PWCHAR pszString; Length = StrLengthA(lpString); pszString = (PWCHAR)AllocStack(Length * sizeof(*pszString)); CP = IsShiftJISString(lpString, Length) ? CP_SHIFTJIS : CP_GB2312; // CP = CP_SHIFTJIS; MultiByteToWideChar(CP, 0, lpString, Length + 1, pszString, Length * 2); return SetWindowTextW(hWnd, pszString); }
LONG NTAPI ShowExitMessageBox(HWND hWnd, PCSTR Text, PCSTR Caption, UINT Type) { ULONG_PTR Length; PSTR Buffer; Length = StrLengthA(Text) + 1; Buffer = (PSTR)AllocStack(Length + 3); *(PULONG)&Buffer[0] = TAG3('#5C'); CopyMemory(Buffer + 3, Text, Length); return EDAO::GlobalGetEDAO()->AoMessageBox(Buffer) == TRUE ? IDYES : IDNO; }
HWND WINAPI HookCreateWindowExA(DWORD dwExStyle, LPCSTR lpClassName, LPCSTR lpWindowName, DWORD dwStyle, int X, int Y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) { RECT rcWordArea; ULONG Length; LPWSTR ClassName, WindowName; HWND hWnd; Length = StrLengthA(lpClassName) + 1; ClassName = (LPWSTR)AllocStack(Length * sizeof(WCHAR)); AnsiToUnicode(ClassName, Length * sizeof(WCHAR), lpClassName, Length); Length = StrLengthA(lpWindowName) + 1; WindowName = (LPWSTR)AllocStack(Length * sizeof(WCHAR)); AnsiToUnicode(WindowName, Length * sizeof(WCHAR), lpWindowName, Length); hWnd = CreateWindowExW(dwExStyle, ClassName, WindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); if (hWnd == NULL) return hWnd; OrigWndProc = (WNDPROC)SetWindowLongPtrA(hWnd, GWLP_WNDPROC, (LONG_PTR)CMVS_MainWindowProc); DragAcceptFiles(hWnd, TRUE); return hWnd; }
HANDLE NTAPI QqCreateWaitQQProtectThread( PSECURITY_ATTRIBUTES ThreadAttributes, ULONG_PTR StackSize, PTHREAD_START_ROUTINE StartAddress, PVOID Parameter, ULONG CreationFlags, PULONG ThreadId ) { NTSTATUS Status; PVOID Ebp, CallCreateQQProtectExchangeWindow; PROCESS_BASIC_INFORMATION BasicInfo; LOOP_ONCE { if (PtrAnd(Parameter, 0xFFF00000) != 0) continue; Status = NtQueryInformationProcess((HANDLE)Parameter, ProcessBasicInformation, &BasicInfo, sizeof(BasicInfo), nullptr); FAIL_BREAK(Status); if (BasicInfo.UniqueProcessId != CurrentPid()) break; AllocStack(16); Ebp = *((PVOID *)_AddressOfReturnAddress() - 1); CallCreateQQProtectExchangeWindow = *((PVOID *)Ebp + 1); if (*(PBYTE)CallCreateQQProtectExchangeWindow != CALL) break; NtClose((HANDLE)Parameter); *(PULONG_PTR)((PVOID *)Ebp + 1) += GetOpCodeSize(CallCreateQQProtectExchangeWindow); return nullptr; } return HummerCreateThread(ThreadAttributes, StackSize, StartAddress, Parameter, CreationFlags, ThreadId); }
NoInline Bool IsPureBlack(LPVoid lpBitmapToCmp, UInt32 h, UInt32 stride, UInt32 stride_raw, UInt32 bpp) { PByte pbTempRow, pbTemp, pbInput; pbTempRow = (PByte)AllocStack(stride); if (bpp == 32) memset4(pbTempRow, RGBA(1, 1, 1, 255), stride); else if (bpp == 24) memset(pbTempRow, 1, stride); else return False; pbTemp = (PByte)lpBitmapToCmp; for (Int32 i = h; i; --i, pbTemp += stride_raw) if (memcmp(pbTemp, pbTempRow, stride)) return False; return True; }
/* function :: init_event_queue() * arguments :: what section to initialize. * ====================================================== * This function is used to initialize the event queue, * and the first section should be initialized at boot, * the second section should be called after all areas, * players, monsters, etc has been loaded into memory, * and it should contain all maintanence events. */ void init_event_queue(int section) { EVENT_DATA *event; int i; if (section == 1) { for (i = 0; i < MAX_EVENT_HASH; i++) { eventqueue[i] = AllocList(); } event_free = AllocStack(); global_events = AllocList(); } else if (section == 2) { event = alloc_event(); event->fun = &event_game_tick; event->type = EVENT_GAME_TICK; add_event_game(event, 10 * 60 * PULSES_PER_SECOND); } }
VOID AppendPackage() { PLDR_MODULE Self; UNICODE_STRING SelfPath; static WCHAR PythonZip[] = L"python.zip"; ml::MlInitialize(); //Py_IgnoreEnvironmentFlag = TRUE; //Py_NoSiteFlag = TRUE; Py_DontWriteBytecodeFlag = TRUE; //Py_NoUserSiteDirectory = TRUE; Self = FindLdrModuleByHandle(nullptr); SelfPath = Self->FullDllName; SelfPath.Length -= Self->BaseDllName.Length; Py_SetPath(ml::String::Format( L"%wZ;%wZ%s;%wZ%s\\site-packages;%wZlib;%wZDLLs;%wZUserSite", &SelfPath, // exe path &SelfPath, PythonZip, // ./python.zip &SelfPath, PythonZip, // ./python.zip/site-packages &SelfPath, // ./lib &SelfPath, // ./DLLs &SelfPath // ./UserSite )); ml::String PathEnv, UserSite; PWSTR EnvBuffer; ULONG Length; UNICODE_STRING Path; RtlInitEmptyString(&Path); RtlExpandEnvironmentStrings_U(nullptr, &USTR(L"%Path%"), &Path, &Length); EnvBuffer = (PWSTR)AllocStack(Length); RtlInitEmptyString(&Path, EnvBuffer, Length); RtlExpandEnvironmentStrings_U(nullptr, &USTR(L"%Path%"), &Path, nullptr); UserSite = SelfPath; UserSite += L"UserSite"; PathEnv = SelfPath; PathEnv += L"DLLs;"; EnumDirectoryFiles( nullptr, L"*.*", 0, UserSite, nullptr, [] (PVOID Buffer, PWIN32_FIND_DATAW FindData, ULONG_PTR Context) -> LONG { ml::String *PathEnv = (ml::String *)Context; if (FLAG_OFF(FindData->dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY)) return 0; (*PathEnv) += FindData->cFileName; (*PathEnv) += ';'; return 0; }, (ULONG_PTR)&PathEnv, EDF_PROCDIR | EDF_BEFORE ); PathEnv += Path; PathEnv += ';'; RtlSetEnvironmentVariable(nullptr, &USTR(L"Path"), PathEnv); }
Quaddon::Quaddon(char *path, image_id id, int n): Stackable(DefineSymbol(AddonName(id,n), S_QUADDON, 0, this, nullptr, REF_VALUE, ATTRIB_NONE, false, DISP_MODE_NOT)) { status_t err; srcImage = id; srcIndex = n; fprintf(stderr, "addon %s, image %d, hook %d: name %s\n", path, id, n, sym->name); uint32 *addon_id_p; if ((err=get_image_symbol( id, "addon_id", B_SYMBOL_TYPE_DATA, (void**)&addon_id_p)) >= B_NO_ERROR) { subType = *addon_id_p; } else if ((err=get_image_symbol( id, "addon_id_array", B_SYMBOL_TYPE_DATA, (void**)&addon_id_p)) >= B_NO_ERROR) { subType = addon_id_p[n]; } else { subType = 0; } char **addon_formal_p; if ((err=get_image_symbol( id, "addon_params", B_SYMBOL_TYPE_DATA, (void **)&addon_formal_p)) >= B_NO_ERROR) { controlVariableDef = new char[strlen(*addon_formal_p)+1]; strcpy(controlVariableDef, *addon_formal_p); } else if ((err=get_image_symbol( id, "addon_params_array", B_SYMBOL_TYPE_DATA, (void**)&addon_formal_p)) >= B_NO_ERROR) { controlVariableDef = new char[strlen(addon_formal_p[n])+1]; strcpy(controlVariableDef, addon_formal_p[n]); } else { controlVariableDef = new char[strlen("()")+1]; strcpy(controlVariableDef, "()"); } InitFnPtr *addon_init_array_p; if ((err=get_image_symbol( id, "init", B_SYMBOL_TYPE_TEXT, (void**)&init)) >= B_NO_ERROR) { ; } else if ((err=get_image_symbol( id, "init_array", B_SYMBOL_TYPE_DATA, (void**)&addon_init_array_p)) >= B_NO_ERROR) { init = addon_init_array_p[n]; } else { init = nullptr; } DisInitFnPtr *addon_disinit_array_p; if ((err=get_image_symbol( id, "disinit", B_SYMBOL_TYPE_TEXT, (void**)&disInit)) >= B_NO_ERROR) { ; } else if ((err=get_image_symbol( id, "disinit_array", B_SYMBOL_TYPE_DATA, (void**)&addon_disinit_array_p)) >= B_NO_ERROR) { disInit = addon_disinit_array_p[n]; } else { disInit = nullptr; } ApplyFnPtr *addon_apply_array_p; if ((err=get_image_symbol( id, "apply", B_SYMBOL_TYPE_TEXT, (void **)&apply)) >= B_NO_ERROR) { ; } else if ((err=get_image_symbol( id, "apply_array", B_SYMBOL_TYPE_DATA, (void**)&addon_apply_array_p)) >= B_NO_ERROR) { apply = addon_apply_array_p[n]; } else { apply = nullptr; } ResetFnPtr *addon_reset_array_p; if ((err=get_image_symbol( id, "reset", B_SYMBOL_TYPE_TEXT, (void**)&reset)) >= B_NO_ERROR) { ; } else if ((err=get_image_symbol( id, "reset_array", B_SYMBOL_TYPE_DATA, (void**)&addon_reset_array_p)) >= B_NO_ERROR) { reset = addon_reset_array_p[n]; } else { reset = nullptr; } SetParamFnPtr *addon_setp_array_p; if ((err=get_image_symbol( id, "set_parameters", B_SYMBOL_TYPE_TEXT, (void**)&setParameters)) >= B_NO_ERROR) { ; } else if ((err=get_image_symbol( id, "set_parameters_array", B_SYMBOL_TYPE_DATA, (void**)&addon_setp_array_p)) >= B_NO_ERROR) { setParameters = addon_setp_array_p[n]; } else { setParameters = nullptr; } // allocate a pointer on the stack for the cookie... cookieVar.Set(S_STRANGE_POINTER, REF_STACK, sym, (long)AllocStack(sym, S_STRANGE_POINTER, 1)); TxtParser *p = new TxtParser(controlVariableDef, path, nullptr); p->GetToken(); p->ParseFormalsList(sym); next = nullptr; }
NTSTATUS CheckIsExplorer() { NTSTATUS Status; PLDR_MODULE Module; PWSTR FullPath, BackSlash; ULONG ReturnLength; ULONG_PTR Length; MEMORY_BASIC_INFORMATION MemoryBasic; PPROCESS_IMAGE_FILE_NAME ExeFileName; PMEMORY_MAPPED_FILENAME_INFORMATION NtdllFileName; MEMORY_MAPPED_FILENAME_INFORMATION LocalMapped; static WCHAR ExplorerName[] = L"explorer.exe"; Status = NtQueryVirtualMemory(CurrentProcess, NtClose, MemoryMappedFilenameInformation, &LocalMapped, sizeof(LocalMapped), &Length); if (Status != STATUS_INFO_LENGTH_MISMATCH && Status != STATUS_BUFFER_OVERFLOW) return Status; NtdllFileName = (PMEMORY_MAPPED_FILENAME_INFORMATION)AllocStack(Length); Status = NtQueryVirtualMemory(CurrentProcess, NtClose, MemoryMappedFilenameInformation, NtdllFileName, Length, &Length); FAIL_RETURN(Status); Status = NtQueryInformationProcess(CurrentProcess, ProcessImageFileName, nullptr, 0, &ReturnLength); if (Status != STATUS_INFO_LENGTH_MISMATCH) return Status; ExeFileName = (PPROCESS_IMAGE_FILE_NAME)AllocStack(ReturnLength); Status = NtQueryInformationProcess(CurrentProcess, ProcessImageFileName, ExeFileName, ReturnLength, &ReturnLength); FAIL_RETURN(Status); BackSlash = nullptr; Length = NtdllFileName->Name.Length / sizeof(WCHAR) - 1; for (; Length != 0; --Length) { if (NtdllFileName->Name.Buffer[Length] != '\\') continue; if (BackSlash != nullptr) { BackSlash = &NtdllFileName->Name.Buffer[Length]; break; } BackSlash = &NtdllFileName->Name.Buffer[Length]; } if (BackSlash == nullptr) return STATUS_NO_MATCH; ++BackSlash; if (PtrOffset(BackSlash, NtdllFileName->Name.Buffer) + sizeof(ExplorerName) > NtdllFileName->Name.MaximumLength) return STATUS_NO_MATCH; CopyStruct(BackSlash, ExplorerName, sizeof(ExplorerName)); NtdllFileName->Name.Length = PtrOffset(BackSlash + CONST_STRLEN(ExplorerName), NtdllFileName->Name.Buffer); Status = RtlEqualUnicodeString(&NtdllFileName->Name, &ExeFileName->ImageFileName, TRUE) ? STATUS_SUCCESS : STATUS_NO_MATCH; return Status; }
RtlFreeUnicodeString(&ExePath); return STATUS_NO_MEMORY; } GlobalRedirectEntry = RedirectEntry; ExePath.Length -= Module->BaseDllName.Length; Length = 0; FOR_EACH(Entry, RedirectSubDirectory, countof(RedirectSubDirectory)) { Length = ML_MAX(Entry->Original.Length, ML_MAX(Entry->Redirected.Length, Length)); } Length += ExePath.Length; Buffer = (PWSTR)AllocStack(Length + sizeof(WCHAR)); FOR_EACH(Entry, RedirectSubDirectory, countof(RedirectSubDirectory)) { CopyMemory(Buffer, ExePath.Buffer, ExePath.Length); CopyMemory(PtrAdd(Buffer, ExePath.Length), Entry->Original.Buffer, Entry->Original.Length); *PtrAdd(Buffer, ExePath.Length + Entry->Original.Length) = 0; RtlCreateUnicodeString(&RedirectEntry->Original, Buffer); CopyMemory(PtrAdd(Buffer, ExePath.Length), Entry->Redirected.Buffer, Entry->Redirected.Length); *PtrAdd(Buffer, ExePath.Length + Entry->Redirected.Length) = 0; RtlCreateUnicodeString(&RedirectEntry->Redirected, Buffer); ++RedirectEntry; }
NTSTATUS ModifySelfSizeOfImage(LPWSTR ExeFullPath, LPWSTR CommandLine, ULONG SizeOfImage) { BOOL Result; ULONG Length; PVOID FakeCPInfoBuffer; WCHAR CmdFullPath[MAX_NTPATH]; PWCHAR CmdLineBuffer; NTSTATUS Status; PLDR_MODULE LdrModule; PIMAGE_DOS_HEADER DosHeader; PIMAGE_NT_HEADERS NtHeader; PIMAGE_SECTION_HEADER SectionHeader; FAKE_CREATE_PROCESS_INFO *fcpi; PROCESS_INFORMATION ProcessInformation; CONTEXT Context; NtFileDisk file; UNICODE_STRING ExeNtPath, *ProcessCommandLine; UNREFERENCED_PARAMETER(CommandLine); LdrModule = Nt_FindLdrModuleByName(NULL); DosHeader = (PIMAGE_DOS_HEADER)&__ImageBase; NtHeader = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHeader + DosHeader->e_lfanew); fcpi = (FAKE_CREATE_PROCESS_INFO *)AllocStack(0x2000); fcpi->PeHeaderSize = (ULONG_PTR)(IMAGE_FIRST_SECTION(NtHeader) + NtHeader->FileHeader.NumberOfSections) - (ULONG_PTR)DosHeader; Status = file.Open(LdrModule->FullDllName.Buffer); if (!NT_SUCCESS(Status)) return Status; Status = file.Read(fcpi->PeHeader, fcpi->PeHeaderSize); if (!NT_SUCCESS(Status)) return Status; CmdLineBuffer = (PWCHAR)((ULONG_PTR)fcpi->PeHeader + fcpi->PeHeaderSize); fcpi->CommandLine.Buffer = CmdLineBuffer; fcpi->CommandLine.Length = (USHORT)(StrLengthW(ExeFullPath) * sizeof(WCHAR)); ProcessCommandLine = &Nt_CurrentPeb()->ProcessParameters->CommandLine; CopyMemory(CmdLineBuffer, ProcessCommandLine->Buffer, ProcessCommandLine->Length); *(PULONG_PTR)&CmdLineBuffer += ProcessCommandLine->Length; CmdLineBuffer[0] = 0; fcpi->CommandLine.Length = ProcessCommandLine->Length; fcpi->CommandLine.MaximumLength = fcpi->CommandLine.Length + sizeof(WCHAR); ++CmdLineBuffer; CmdLineBuffer = (PWCHAR)ROUND_UP((ULONG_PTR)CmdLineBuffer, 16); RtlDosPathNameToNtPathName_U(LdrModule->FullDllName.Buffer, &ExeNtPath, NULL, NULL); fcpi->ExeNtPath.Buffer = CmdLineBuffer; CopyMemory(CmdLineBuffer, ExeNtPath.Buffer, ExeNtPath.Length); *(PULONG_PTR)&CmdLineBuffer += ExeNtPath.Length; CmdLineBuffer[0] = 0; fcpi->ExeNtPath.Length = ExeNtPath.Length; fcpi->ExeNtPath.MaximumLength = fcpi->ExeNtPath.Length + sizeof(WCHAR); *CmdLineBuffer++ = 0; RtlFreeUnicodeString(&ExeNtPath); DosHeader = (PIMAGE_DOS_HEADER)fcpi->PeHeader; NtHeader = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHeader + DosHeader->e_lfanew); SectionHeader = IMAGE_FIRST_SECTION(NtHeader); SectionHeader += NtHeader->FileHeader.NumberOfSections - 1; SizeOfImage -= LdrModule->SizeOfImage; SizeOfImage = ROUND_UP(SizeOfImage, MEMORY_PAGE_SIZE); SectionHeader->Misc.VirtualSize = ROUND_UP(SectionHeader->Misc.VirtualSize, MEMORY_PAGE_SIZE) + SizeOfImage; if (NtHeader->FileHeader.SizeOfOptionalHeader > FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, SizeOfImage) + RTL_FIELD_SIZE(IMAGE_OPTIONAL_HEADER, SizeOfImage)) NtHeader->OptionalHeader.SizeOfImage += SizeOfImage; Length = Nt_GetSystemDirectory(CmdFullPath, countof(CmdFullPath)); StrCopyW(CmdFullPath + Length, L"cmd.exe"); ProcessInformation.hProcess = NtCurrentProcess(); ProcessInformation.hThread = NtCurrentThread(); #if 1 Result = Nt_CreateProcess(NULL, CmdFullPath, NULL, CREATE_SUSPENDED, NULL, &ProcessInformation); if (!Result) return STATUS_UNSUCCESSFUL; #endif FakeCPInfoBuffer = NULL; LOOP_ONCE { ULONG_PTR Offset; Status = NtDuplicateObject( NtCurrentProcess(), NtCurrentProcess(), ProcessInformation.hProcess, &fcpi->ProcessHandle, 0, 0, DUPLICATE_SAME_ACCESS ); if (!NT_SUCCESS(Status)) break; /* Status = NtDuplicateObject( NtCurrentProcess(), file, ProcessInformation.hProcess, &fcpi->FileHandle, 0, 0, DUPLICATE_SAME_ACCESS ); if (!NT_SUCCESS(Status)) break; */ Status = Nt_AllocateMemory(ProcessInformation.hProcess, &FakeCPInfoBuffer, MEMORY_PAGE_SIZE); if (!NT_SUCCESS(Status)) break; fcpi->CreateProcessInternalW = CreateProcessInternalW; fcpi->NtTerminateProcess = NtTerminateProcess; fcpi->LdrShutdownProcess = LdrShutdownProcess; fcpi->NtCreateFile = NtCreateFile; fcpi->NtWriteFile = NtWriteFile; fcpi->NtClose = NtClose; fcpi->NtWaitForSingleObject = NtWaitForSingleObject; fcpi->InitialDirectory.Buffer = NULL; Offset = (ULONG_PTR)FakeCPInfoBuffer - (ULONG_PTR)fcpi; *(PULONG_PTR)&fcpi->CommandLine.Buffer += Offset; *(PULONG_PTR)&fcpi->ExeNtPath.Buffer += Offset; Status = Nt_WriteMemory( ProcessInformation.hProcess, FakeCPInfoBuffer, fcpi, (ULONG_PTR)CmdLineBuffer - (ULONG_PTR)fcpi, &Length ); if (!NT_SUCCESS(Status)) break; Context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; Status = NtGetContextThread(ProcessInformation.hThread, &Context); if (!NT_SUCCESS(Status)) break; Context.Eip = (ULONG_PTR)FakeCPInfoBuffer + Length; Context.Eip = ROUND_UP(Context.Eip, 16); Context.Ecx = (ULONG_PTR)FakeCPInfoBuffer; Status = Nt_WriteMemory( ProcessInformation.hProcess, (PVOID)Context.Eip, ModifySizeOfImage, (ULONG_PTR)ModifySizeOfImageEnd - (ULONG_PTR)ModifySizeOfImage, &Length ); if (!NT_SUCCESS(Status)) break; #if 1 Status = NtSetContextThread(ProcessInformation.hThread, &Context); if (!NT_SUCCESS(Status)) break; Status = NtResumeThread(ProcessInformation.hThread, NULL); #else INLINE_ASM jmp Context.Eip; #endif } if (!NT_SUCCESS(Status)) { if (FakeCPInfoBuffer != NULL) Nt_FreeMemory(ProcessInformation.hProcess, FakeCPInfoBuffer); NtTerminateProcess(ProcessInformation.hProcess, 0); } NtClose(ProcessInformation.hProcess); NtClose(ProcessInformation.hThread); return Status; }
NTSTATUS GetRedirectFile(PUNICODE_STRING Redirected, PUNICODE_STRING Original) { ULONG_PTR Length; PWSTR Buffer; UNICODE_STRING FileName; typedef struct { UNICODE_STRING SubPath; ULONG_PTR SuffixLength; PCWSTR NewSubPath; } REDIRECT_ENTRY, *PDB_REDIRECT; PDB_REDIRECT Entry; static REDIRECT_ENTRY RedirectEntries[] = { { RTL_CONSTANT_STRING(L"\\All Users\\QQ\\History.db"), CONST_STRLEN(L"History.db") * sizeof(WCHAR), GlobalHistoryDb }, { RTL_CONSTANT_STRING(L"\\All Users\\QQ\\Registry.db"), CONST_STRLEN(L"Registry.db") * sizeof(WCHAR), GlobalRegistryDb }, //{ RTL_CONSTANT_STRING(L"QQProtect.exe"), CONST_STRLEN(L"QQProtect.exe") * sizeof(WCHAR), NULL }, }; RtlInitEmptyString(Redirected); LOOP_ONCE { if (Original == nullptr) continue; FOR_EACH_ARRAY(Entry, RedirectEntries) { if (Original->Length <= Entry->SubPath.Length) continue; FileName = *Original; FileName.Buffer = PtrSub(PtrAdd(FileName.Buffer, FileName.Length), Entry->SubPath.Length); FileName.Length = Entry->SubPath.Length; if (!RtlEqualUnicodeString(&FileName, &Entry->SubPath, TRUE)) continue; /* if (Entry->NewSubPath == NULL) { ExceptionBox(L"qqprotect"); ++Entry; } */ break; } if (Entry == &RedirectEntries[countof(RedirectEntries)]) break; Length = Original->Length + Entry->SubPath.Length + Entry->SuffixLength + sizeof(Entry->NewSubPath); Buffer = (PWSTR)AllocStack(Length); FileName.MaximumLength = Length; FileName.Buffer = Buffer; Length = StrLengthW(Entry->NewSubPath) * sizeof(WCHAR); RtlCopyUnicodeString(&FileName, Original); CopyMemory(PtrSub(PtrAdd(FileName.Buffer, FileName.Length), Entry->SuffixLength), Entry->NewSubPath, Length + sizeof(WCHAR)); FileName.Length = FileName.Length - Entry->SuffixLength + Length; RtlDuplicateUnicodeString(RTL_DUPSTR_ADD_NULL, &FileName, Redirected); return STATUS_SUCCESS; } return STATUS_NOT_FOUND; }