[ollydbg] another trick to bypass winlicense 2.1.1.0 under xp/2003 RtlUnicodeToMultiByteN
I have found some interesting things missing from IDAStealth so you may be interested to look in these procedures, I name OllyStealth the plugin Im designing for OllyDBG mainly based on your plugin and I notice it requires patches to run because OllyDBG is found but I have found the right hooks to apply to bypass winlicense on XP+Win2003+Win7
*** = not in IDAStealth
Under Windows 7 + OllyStealth against Winlicense 2.1.1.0
1 - IsDebuggerPresent (patch peb.beingdebugged)
2 - NtGlobalFlag (patch global heap flags)
3 - Fake parent process (change to explorer.exe)
4 - RtlGetNtGlobalFlags (prevent debug heap initialization)
5 - Fake GetWindowTextA (fake return value) ***
Under WinXP/2003 + OllyStealth against Winlicense 2.1.1.0
1 - IsDebuggerPresent (patch peb.beingdebugged)
2 - NtGlobalFlag (patch global heap flags)
3 - Fake parent process (change to explorer.exe)
4 - RtlGetNtGlobalFlags (prevent debug heap initialization)
5 - Fake RtlUnicodeToMultiByteN (fake return value) ***
Under windows7 GetWindowTextA is called to check for the word "C.P.U" in the window caption
Under XP/2003 it was more problematic, GetWindowText* was never called and after hours of research I have found out it used to scan a pattern after the use of an undocumented MSDN api called GdiDllInitialize, it imported a buffer with the ollydbg title "C.P.U" in it but in unicode, and it used RtlUnicodeToMultiByteN to convert it in a readable form in the heap. Hooking RtlUnicodeToMultiByteN
NTSTATUS NTAPI RtlUnicodeToMultiByteNHook(PCHAR MultiByteString,
ULONG MaxBytesInMultiByteString,
PULONG BytesInMultiByteString,
PCWCH UnicodeString,
ULONG BytesInUnicodeString)
{
origRtlUnicodeToMultiByteN(MultiByteString,MaxBytesInMultiByteString,BytesInMultiByteString,UnicodeString,BytesInUnicodeString);
const string& name = MultiByteString;
const char* names[] = { "thread", "main", "ollydbg", "c.p.u", "module" };
string tmp(name.length(), 0);
transform(name.begin(), name.end(), tmp.begin(), tolower);
for (int i=0; i
something simple like that is the 5th patch to bypass wl 2.1.1.0 with olly, idaollystealth under xp
btw this is class101, not
btw this is class101, not annonymous =)
I have updated the function
I have updated the function proper way, teh function below works around winlicense 2.x on both Win7 and WinXP (and probably more), it pass over GetWindowText for Win7 so under Win7 you have the choice to hook GetWindowText? or RtlUnicodeToMultiByteN, underXP RtlUnicodeToMultiByteN only
NTSTATUS NTAPI RtlUnicodeToMultiByteNHook(PCHAR MultiByteString,
ULONG MaxBytesInMultiByteString,
PULONG BytesInMultiByteString,
PCWCH UnicodeString,
ULONG BytesInUnicodeString)
{
CHAR FakeBuff[248];
//if (origRtlUnicodeToMultiByteN(FakeBuff,MaxBytesInMultiByteString,BytesInMultiByteString,UnicodeString,BytesInUnicodeString) != STATUS_SUCCESS);
//return -1;
int r = origRtlUnicodeToMultiByteN(FakeBuff,MaxBytesInMultiByteString,BytesInMultiByteString,UnicodeString,BytesInUnicodeString);
if (r != STATUS_SUCCESS) return -1;
const string& name = FakeBuff;
const char* names[] = { "[CPU -", "main thread,", ", module ", "OllyDbg - " };
string tmp(name.length(), 0);
transform(name.begin(), name.end(), tmp.begin(), tolower);
for (int i=0; i
this is a nice method that GetWindowText? because RtlUnicodeToMultiByteN is like a stub function where winlicense can send patterns used to find ollydbg
In this case the hook on RtlUnicodeToMultiByteN restrict Winlicense from exporting the background window title in its heap, so the part of the winlicense memory where was stored the ollydbg title is now blank and we pass over protection ;)
previous post incomplete
previous post incomplete sorry (site formatting)
NTSTATUS NTAPI RtlUnicodeToMultiByteNHook(PCHAR MultiByteString, ULONG MaxBytesInMultiByteString, PULONG BytesInMultiByteString, PCWCH UnicodeString, ULONG BytesInUnicodeString) { CHAR FakeBuff[248]; //if (origRtlUnicodeToMultiByteN(FakeBuff,MaxBytesInMultiByteString,BytesInMultiByteString,UnicodeString,BytesInUnicodeString) != STATUS_SUCCESS); //return -1; int r = origRtlUnicodeToMultiByteN(FakeBuff,MaxBytesInMultiByteString,BytesInMultiByteString,UnicodeString,BytesInUnicodeString); if (r != STATUS_SUCCESS) return -1; const string& name = FakeBuff; const char* names[] = { "[CPU -", "main thread,", ", module ", "OllyDbg - " }; string tmp(name.length(), 0); transform(name.begin(), name.end(), tmp.begin(), tolower); for (int i=0; i<ARRAYSIZE(names); ++i){ if (tmp.find(names[i]) != string::npos) return STATUS_SUCCESS; } return origRtlUnicodeToMultiByteN(MultiByteString,MaxBytesInMultiByteString,BytesInMultiByteString,UnicodeString,BytesInUnicodeString); }