void AdditiveCipherTemplate<S>::GenerateBlock(byte *outString, size_t length) { if (m_leftOver > 0) { const size_t len = STDMIN(m_leftOver, length); memcpy(outString, PtrSub(KeystreamBufferEnd(), m_leftOver), len); length -= len; m_leftOver -= len; outString = PtrAdd(outString, len); if (!length) {return;} } PolicyInterface &policy = this->AccessPolicy(); unsigned int bytesPerIteration = policy.GetBytesPerIteration(); if (length >= bytesPerIteration) { const size_t iterations = length / bytesPerIteration; policy.WriteKeystream(outString, iterations); length -= iterations * bytesPerIteration; outString = PtrAdd(outString, iterations * bytesPerIteration); } if (length > 0) { size_t bufferByteSize = RoundUpToMultipleOf(length, bytesPerIteration); size_t bufferIterations = bufferByteSize / bytesPerIteration; policy.WriteKeystream(PtrSub(KeystreamBufferEnd(), bufferByteSize), bufferIterations); memcpy(outString, PtrSub(KeystreamBufferEnd(), bufferByteSize), length); m_leftOver = bufferByteSize - length; } }
void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inString, size_t length) { if (m_leftOver > 0) { const size_t len = STDMIN(m_leftOver, length); xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len); length -= len; m_leftOver -= len; inString = PtrAdd(inString, len); outString = PtrAdd(outString, len); } PolicyInterface &policy = this->AccessPolicy(); unsigned int bytesPerIteration = policy.GetBytesPerIteration(); if (policy.CanOperateKeystream() && length >= bytesPerIteration) { const size_t iterations = length / bytesPerIteration; unsigned int alignment = policy.GetAlignment(); KeystreamOperation operation = KeystreamOperation((IsAlignedOn(inString, alignment) * 2) | (int)IsAlignedOn(outString, alignment)); policy.OperateKeystream(operation, outString, inString, iterations); inString = PtrAdd(inString, iterations * bytesPerIteration); outString = PtrAdd(outString, iterations * bytesPerIteration); length -= iterations * bytesPerIteration; } size_t bufferByteSize = m_buffer.size(); size_t bufferIterations = bufferByteSize / bytesPerIteration; while (length >= bufferByteSize) { policy.WriteKeystream(m_buffer, bufferIterations); xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize); length -= bufferByteSize; inString = PtrAdd(inString, bufferByteSize); outString = PtrAdd(outString, bufferByteSize); } if (length > 0) { bufferByteSize = RoundUpToMultipleOf(length, bytesPerIteration); bufferIterations = bufferByteSize / bytesPerIteration; policy.WriteKeystream(PtrSub(KeystreamBufferEnd(), bufferByteSize), bufferIterations); xorbuf(outString, inString, PtrSub(KeystreamBufferEnd(), bufferByteSize), length); m_leftOver = bufferByteSize - length; } }
PVOID NTAPI HookRtlAllocateHeap(HANDLE HeapBase, ULONG Flags, SIZE_T Bytes) { ULONG_PTR Protect, Size; PVOID First, Memory, Second; Size = ROUND_UP(Bytes, MEMORY_PAGE_SIZE) + MEMORY_PAGE_SIZE * 2; Memory = NULL; Nt_AllocateMemory(NtCurrentProcess(), &Memory, Size, PAGE_EXECUTE_READWRITE, MEM_RESERVE); Nt_AllocateMemory(NtCurrentProcess(), &Memory, Size - MEMORY_PAGE_SIZE, PAGE_EXECUTE_READWRITE, MEM_COMMIT); Second = PtrAdd(Memory, Size - MEMORY_PAGE_SIZE); Nt_AllocateMemory(NtCurrentProcess(), &Second, MEMORY_PAGE_SIZE, PAGE_READONLY, MEM_COMMIT); Memory = PtrSub(Second, Bytes); *(PULONG_PTR)PtrSub(Memory, sizeof(PVOID)) = Bytes; return Memory; }
TAny* TSglQueIterBase::DoPostInc() // // Return the current pointer and increment. // { TAny* pN = iNext; if (pN == NULL) return NULL; iNext = iNext->iNext; return PtrSub(pN, iOffset); }
void AdditiveCipherTemplate<BASE>::Seek(lword position) { PolicyInterface &policy = this->AccessPolicy(); word32 bytesPerIteration = policy.GetBytesPerIteration(); policy.SeekToIteration(position / bytesPerIteration); position %= bytesPerIteration; if (position > 0) { policy.WriteKeystream(PtrSub(KeystreamBufferEnd(), bytesPerIteration), 1); m_leftOver = bytesPerIteration - static_cast<word32>(position); } else m_leftOver = 0; }
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; }
BOOL HookCallCreateProcessFast(PVOID InvokeReturnAddress) { PBYTE InvokeBuffer; PVOID *JumpAddressBegin, *JumpAddressEnd, HookRoutine; PIMAGE_NT_HEADERS NtHeaders; PLDR_MODULE Shell32; InvokeBuffer = (PBYTE)InvokeReturnAddress; LOOP_ONCE { if (*(PUSHORT)&InvokeBuffer[-6] != 0x15FF) continue; #if ML_X86 if (*(PULONG)&InvokeBuffer[-4] != (ULONG)Shell32CreateProcessWIAT) break; #elif ML_AMD64 if ((PVOID)PtrAdd(InvokeBuffer, *(PULONG)&InvokeBuffer[-4]) != Shell32CreateProcessWIAT) break; #endif // arch Shell32 = FindLdrModuleByName(&WCS2US(L"SHELL32.dll")); NtHeaders = RtlImageNtHeader(Shell32->DllBase); if (NtHeaders == nullptr) break; JumpAddressEnd = (PVOID *)PtrAdd(Shell32->DllBase, ROUND_UP(NtHeaders->OptionalHeader.SizeOfHeaders, NtHeaders->OptionalHeader.SectionAlignment)); JumpAddressBegin = (PVOID *)(IMAGE_FIRST_SECTION(NtHeaders) + NtHeaders->FileHeader.NumberOfSections); JumpAddressBegin = (PVOID *)ROUND_UP((ULONG_PTR)JumpAddressBegin, 16); while (JumpAddressBegin < JumpAddressEnd) { #if ML_X86 if ( JumpAddressBegin[0] == nullptr && JumpAddressBegin[1] == nullptr && JumpAddressBegin[2] == nullptr && JumpAddressBegin[3] == nullptr ) { break; } JumpAddressBegin += 4; #else if ( JumpAddressBegin[0] == nullptr && JumpAddressBegin[1] == nullptr ) { break; } JumpAddressBegin += 2; #endif } if (JumpAddressBegin >= JumpAddressEnd) break; HookRoutine = SpeedUpCreateProcessW; WriteProtectMemory(CurrentProcess, JumpAddressBegin, &HookRoutine, sizeof(HookRoutine)); #if ML_X86 WriteProtectMemory(CurrentProcess, &InvokeBuffer[-4], &JumpAddressBegin, sizeof(JumpAddressBegin)); #elif ML_AMD64 LONG64 RelateOffset; RelateOffset = (TYPE_OF(RelateOffset))PtrSub(JumpAddressBegin, InvokeBuffer); WriteProtectMemory(CurrentProcess, &InvokeBuffer[-4], &RelateOffset, sizeof(LONG)); #endif return TRUE; } return FALSE; }
BOOL NTAPI HookRtlFreeHeap(HANDLE HeapBase, ULONG Flags, LPVOID Memory) { Memory = (PVOID)ROUND_DOWN((ULONG_PTR)Memory, MEMORY_PAGE_SIZE); Nt_FreeMemory(NtCurrentProcess(), PtrSub(Memory, MEMORY_PAGE_SIZE)); return TRUE; }