Introduction
How to make device support for Unicode by hacking InitLocale
function inside coredll.dll in the entire system, not your application, this way to set your Arabic Locale in the entire System to be able to Save Arabic on File. Without this, you can't save Arabic inside file or save note or appointment or calendar.
Note: We used this way to all device manufacture such as HTC, ASUS, InterMek, etc. since the device comes without Arabic Locale.
Background
Most of the application tries to read some information from Local, By Function inside Framework or MFC, etc., whatever language you used, all Framework should call InitLocal
function inside coredll.dll so what you need actually in this case, hook this function.
Using the Code
As we mentioned before, we have to obtain pointer for InitLocale
function inside coredll.dll and save it inside fpInitlocale
to use it later. We will talk more about that.
Also, we need to CreateMutex
, BTW, it's good to know what mutex means:
CreateMutex
: A mutex is a synchronization object that negotiates mutual exclusion among threads of a single process to avoid simultaneous modifications on common resources such as global variables.
HINSTANCE hinstCore = (HINSTANCE)GetModuleHandle(L"COREDLL");
FARPROC fpInitLocale = GetProcAddress(hinstCore,L"InitLocale");
HANDLE _nlsMutex=CreateMutex(NULL,0,L"NLSMUTEX");
HANDLE _nlsHeap=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,4,0,0x10000,L"NLSHEAP");
Now to share memory between processes, you have to use CreateFileForMapping
to make your locale shared between all processes:
HANDLE hNLSFile, hNLSMap, hNLSOrig;
hNLSFile = CreateFileForMapping(nlsFile,GENERIC_READ,0,0,OPEN_EXISTING,0,0);
hNLSMap = CreateFileMapping(hNLSFile,0,PAGE_READONLY,0,0,L"some nice string longer that 7 chars");
FSMAP *nls = HandleToMap(hNLSMap);
hNLSOrig = CreateFileMapping(INVALID_HANDLE_VALUE,0,PAGE_READONLY,0,0,L"NLSFILE");
LPVOID origView=MapViewOfFile(hNLSOrig,6,0,0,0);
FSMAP *orig = HandleToMap(hNLSOrig);
The trick of the code here is to rename the original Name (to make them invisible) because all of...
...already cached inside running process.
orig->name->name[0]='_';
wcscpy(nls->name->name, L"NLSFILE");
FSMAP *nlsHeap= HandleToMap(hNLSOrig);
nlsHeap->name->name[0]='_';
MUTEX *m = HandleToMutex(_nlsMutex);
m->name->name[0]='_';
Now, we will go to All running Process and inject our NLSFILE
and NLSMUTEX
instead of the original one.
PROCESSENTRY32 pe32;
HANDLE hSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | 0x40000000 , NULL);
pe32.dwSize=sizeof(pe32);
BOOL bb=Process32First(hSnap,&pe32);
while (bb) {
CallInProcess(pe32.th32ProcessID, fpInitLocale, NULL);
pe32.dwSize=sizeof(pe32);
bb=Process32Next(hSnap, &pe32);
}
CloseToolhelp32Snapshot(hSnap);
Finally, to use this code, add nls.cpp inside your process and call this function:
PatchNLS("\windows\younls.nls");