Author Topic: Re: War2 100% of 1 core CPU load - CPU Savior, version 2  (Read 9128 times)

Offline iL

  • Administrator
  • Ogre Mage
  • *****
  • Posts: 1653
    • View Profile
Re: War2 100% of 1 core CPU load - CPU Savior, version 2
« on: April 04, 2016, 06:04:25 AM »
Let me share the source code for this project.
Looks like I adandoned that project, maybe somebody will fix crashes for win8-10 also...
Maybe i will some day, but not sure if i have enough time or not.

This: https://bitbucket.org/ilwar2/war2-cpu-savior

Let me know if something wrong: my first git repository :)
Need help to translate War2Combat to German, French, Italian, Polish or another language: http://forum.war2.ru/index.php/topic,4728.0.html
Please, contact me if you are interested in that.

Offline iL

  • Administrator
  • Ogre Mage
  • *****
  • Posts: 1653
    • View Profile
Re: Re: War2 100% of 1 core CPU load - CPU Savior, version 2
« Reply #1 on: April 04, 2016, 06:39:44 AM »
If people have a Win8/10 system, there is less of a possibility that they might need it (powerful enough system)!
I actually don't mean it 100% works on win-non 8/10 and doesn't work on others. That just caused crash on my test win8/10 platforms and didn't on winxp/vista/7. Maybe that was just my luck/unluck.

Did you try version 2 (cpusavior_cmd) or version 1 (cpusavior_il)?
Did it work stable for you?

I just got an idea that address GETPROP_ADDR 0x150452A4 is not the same for every system.
Hm, or depends on x86 or x64 os? Which OS do you have?
Need help to translate War2Combat to German, French, Italian, Polish or another language: http://forum.war2.ru/index.php/topic,4728.0.html
Please, contact me if you are interested in that.

Offline Warchief Lightbringer-

  • Server Admin
  • Axe Thrower
  • *****
  • Posts: 428
    • View Profile
Re: Re: War2 100% of 1 core CPU load - CPU Savior, version 2
« Reply #2 on: April 04, 2016, 06:46:31 AM »
I use V2. Have Windows 7 X86 :)
aka DeaDLyGaMeS

Offline aqrit

  • Peon
  • **
  • Posts: 41
    • View Profile
Re: Re: War2 100% of 1 core CPU load - CPU Savior, version 2
« Reply #3 on: April 04, 2016, 11:38:23 PM »
the dll can be rebased but the exe can not, so the trick is to pull the dll address from the exe IAT.

any reason to avoid patching in-place?

this untested example code makes my eyes bleed less  :'(
Code: [Select]
void CpuSaver_Hook_Storm208( HANDLE hProcess ){
DWORD dwPrevProtect;
DWORD storm208_va;
DWORD offset = 0x15011370 - 0x150112E0;
BYTE data[] = { 0x89, 0xE8, 0x83, 0xE8, 0x3C, 0x6A, 0x01, 0xFF, 0xD0, 0xEB, 0xE2, 0x90 };
ReadProcessMemory( hProcess, (void*)0x004902C8, storm208_va, 4, 0 );
VirtualProtectEx(  hProcess, storm208_va + offset, sizeof(data), PAGE_EXECUTE_READWRITE, &dwPrevProtect );
WriteProcessMemory( hProcess, storm208_va + offset, data, sizeof(data), 0 );
VirtualProtectEx( hProcess, storm208_va + offset, sizeof(data), dwPrevProtect, &dwPrevProtect );
}
Spoiler
Code: [Select]
/*
old:
1501135D 68 247D0315         PUSH OFFSET 15037D24 ; "SDlg_EndDialog"
15011362 56                  PUSH ESI             ; hWnd
15011363 FFD3                CALL EBX             ; USER32.GetPropA
15011365 85C0                TEST EAX,EAX
15011367 75 13               JNZ SHORT 1501137C
15011369 8BCE                MOV ECX,ESI
1501136B E8 40FAFFFF         CALL 15010DB0     
15011370 68 247D0315         PUSH OFFSET 15037D24 ; "SDlg_EndDialog"
15011375 56                  PUSH ESI             ; hWnd
15011376 FFD3                CALL EBX             ; USER32.GetPropA
15011378 85C0                TEST EAX,EAX
1501137A 74 ED               JZ SHORT 15011369

new:
...
15011370 89E8                MOV EAX,EBP // ptr to GetPropA
15011372 83E8 3C             SUB EAX,3C // adjust to point at Sleep
15011375 6A 01               PUSH 1
15011377 FFD0                CALL EAX
15011379 EB E2               JMP SHORT 1501135D // loop to GetPropA
1501137B 90                  NOP
*/

Offline iL

  • Administrator
  • Ogre Mage
  • *****
  • Posts: 1653
    • View Profile
Re: Re: War2 100% of 1 core CPU load - CPU Savior, version 2
« Reply #4 on: April 05, 2016, 07:17:50 PM »
any reason to avoid patching in-place?
Well, i just copied the idea from R!CH project, similar solution :P

aqrit, your idea looks much better!
I just didn't understand how you understood that storm208 is what we need.

I opened storm.dll in IDA and looked into 15011378 (address after: call    ebx ; GetPropA)
It belongs function called Ordinal208 - is that a key? Ordinal208 == storm208?


I also didn't understand your trick with asm code on 15011370:
why EBP-3C is address of Sleep?

Sorry for stupid questions, i never had experience with dll addressing before...
Need help to translate War2Combat to German, French, Italian, Polish or another language: http://forum.war2.ru/index.php/topic,4728.0.html
Please, contact me if you are interested in that.

Offline aqrit

  • Peon
  • **
  • Posts: 41
    • View Profile
Re: Re: War2 100% of 1 core CPU load - CPU Savior, version 2
« Reply #5 on: April 06, 2016, 02:07:09 AM »
Quote
Ordinal208 == storm208
yeah, IDA just makes up a name for it because it is un-named...
in the "Exports" tab... double-clicking "Storm_208" jumps to "Ordinal208"

This can be checked by looking at it in a debugger,
checking the IAT structure by hand, or using some other tool.

Quote
why EBP-3C is address of Sleep?
That is a typo, EBX is the pointer to GetPropA (not EBP)
which would make the first two bytes of data "89 D8" ( not "89 E8" )

ebx == GetPropA == 0x15033270
Sleep == 0x15033234
0x15033270 - 0x15033234 = 0x3C

Offline iL

  • Administrator
  • Ogre Mage
  • *****
  • Posts: 1653
    • View Profile
Re: Re: War2 100% of 1 core CPU load - CPU Savior, version 2
« Reply #6 on: April 06, 2016, 03:26:55 AM »
yeah, IDA just makes up a name for it because it is un-named...
in the "Exports" tab... double-clicking "Storm_208" jumps to "Ordinal208"

This can be checked by looking at it in a debugger,
checking the IAT structure by hand, or using some other tool.
Thx, just have not been sure that 208 is a constant between exe and dll.
I wasn't able to load both exe and dll into the same IDA instance, so i used if separately (my bad knowledge in IDA).

That is a typo, EBX is the pointer to GetPropA (not EBP)
which would make the first two bytes of data "89 D8" ( not "89 E8" )
I see, just a mistake.
Also i didn't think distance between GetPropA and Sleep is constant in all the systems, past and future. Can it be hardcoded as 3C?

Anyways, i like you idea to find storm208 by address and then to patch it some way. Should 100% work on any system.
Need help to translate War2Combat to German, French, Italian, Polish or another language: http://forum.war2.ru/index.php/topic,4728.0.html
Please, contact me if you are interested in that.

Offline aqrit

  • Peon
  • **
  • Posts: 41
    • View Profile
Re: Re: War2 100% of 1 core CPU load - CPU Savior, version 2
« Reply #7 on: April 06, 2016, 03:53:49 AM »
Quote
GetPropA and Sleep is constant in all the systems, past and future. Can it be hardcoded as 3C?

yeah that is NOT going to work :)
I shouldn't post things without trying them I suppose...

I was thinking it was mov ebx, xxxxx
when it was actually mov ebx, [xxxxx]
/facepalm

Offline iL

  • Administrator
  • Ogre Mage
  • *****
  • Posts: 1653
    • View Profile
Re: Re: War2 100% of 1 core CPU load - CPU Savior, version 2
« Reply #8 on: April 06, 2016, 04:16:30 AM »
yeah that is NOT going to work :)
I shouldn't post things without trying them I suppose...
I see, as you wrote it's just an untested example, thx for it.
You idea with patching in-place is good, you right, i should never use hardcoded 0x15XXXXXX addresses and i can safely use 0x004XXXXX anywhere. I'll try to modify my project...
Need help to translate War2Combat to German, French, Italian, Polish or another language: http://forum.war2.ru/index.php/topic,4728.0.html
Please, contact me if you are interested in that.

Offline Warchief Lightbringer-

  • Server Admin
  • Axe Thrower
  • *****
  • Posts: 428
    • View Profile
Re: Re: War2 100% of 1 core CPU load - CPU Savior, version 2
« Reply #9 on: April 06, 2016, 06:09:59 AM »
Move that thread to development and delete my OT post:)
aka DeaDLyGaMeS

Offline iL

  • Administrator
  • Ogre Mage
  • *****
  • Posts: 1653
    • View Profile
Re: Re: War2 100% of 1 core CPU load - CPU Savior, version 2
« Reply #10 on: April 06, 2016, 06:38:30 AM »
Move that thread to development and delete my OT post:)
You right, i didn't think source code publishing will cause such big discussion...
Need help to translate War2Combat to German, French, Italian, Polish or another language: http://forum.war2.ru/index.php/topic,4728.0.html
Please, contact me if you are interested in that.

Offline aqrit

  • Peon
  • **
  • Posts: 41
    • View Profile
Re: War2 100% of 1 core CPU load - CPU Savior, version 2
« Reply #11 on: April 06, 2016, 11:19:58 AM »
untested but same idea ( no fix-ups needed in the injected code )
Code: [Select]
15011370  6A 01           PUSH 1
15011372  FF15 68014900   CALL DWORD PTR DS:[490168] // Sleep in exe IAT
15011378  EB E3           JMP SHORT 1501135D
1501137A  90              NOP
1501137B  90              NOP

data[] = { 0x6A, 0x01, 0xFF, 0x15, 0x68, 0x01, 0x49, 0x00, 0xEB, 0xE3, 0x90, 0x90 };

Offline Lambchops

  • Ogre Mage
  • ********
  • Posts: 1541
    • View Profile
Re: War2 100% of 1 core CPU load - CPU Savior, version 2
« Reply #12 on: February 22, 2017, 04:54:19 AM »
untested but same idea ( no fix-ups needed in the injected code )
Code: [Select]
15011370  6A 01           PUSH 1
15011372  FF15 68014900   CALL DWORD PTR DS:[490168] // Sleep in exe IAT
15011378  EB E3           JMP SHORT 1501135D
1501137A  90              NOP
1501137B  90              NOP

data[] = { 0x6A, 0x01, 0xFF, 0x15, 0x68, 0x01, 0x49, 0x00, 0xEB, 0xE3, 0x90, 0x90 };


Oh cool.   :)

Somehow missed this thread last year. Must have been busy having a mental breakdown at the time...

Anyway, this is totally the way to go. You can never reliably hard code procedure entry points in external modules. They can be re-mapped by the OS, but in fact almost never are. The other problem is different versions of the same module will shift the entry points for the individual procedures even if the module is mapped at the same base address.

In theory modules can be re-mapped by the OS and they will be in the case where multiple 3rd party modules attempt to use the same address space, but AFAIK for core API modules the only time M$ seriously tried to impliment this was for Vista. It was supposed to be a security feature but ended up being a Pandora's Box of cascading bugs that eventually imploded the whole OS.

But as aqrit points out, the only way to go when linking procedure calls is to use the correct import/export structures. You can always get these from the IMAGE_EXPORT_DIRECTORY but if the proc you want is already imported by the target application, then its much easier to just us the Import Address Table, as the system loader will have already done the work for you.

In the case of WC2 it already imports a fairly decent list of handy API functions, but most notably it imports both LoadLibrary and GetProcAddress. Obviously when you have access to there 2 functions you can always import anything you want to.

the "call DWORD ptr[IAT offset]" method is ideal for injected code. When doing this type of thing I find it handy to to just define the proc names as equates then you only need to add the square brackets to call instructions. i.e.

Code: [Select]
Sleep            equ  490168h

.code

push 50
call [Sleep]

If you keep your equates in a seperate include, you can swap them in/out in exchange for standard API includes which helps when testing/compiling for injection.

So how did this end up going? I tested it on my system and it seemed to work well in-game, but not in the chat channel. Did this ever end up being fixed?


Here's an ASM include for the Kernel32 procs imported by WC2:

Code: [Select]
; CloseHandle(HANDLE hObject)
  CloseHandle                   equ 490160h

; CompareStringA(LCID Locale,DWORD dwCmpFlags,LPCSTR lpString1,int cchCount1,LPCSTR lpString2,int cchCount2)
  CompareStringA                equ 490088h

; CompareStringW(LCID Locale,DWORD dwCmpFlags,LPCWSTR lpString1,int cchCount1,LPCWSTR lpString2,int cchCount2)
  CompareStringW                equ 490084h

; CreateDirectoryA(LPCSTR lpPathName,LPSECURITY_ATTRIBUTES lpSecurityAttributes)
  CreateDirectoryA              equ 490078h

; CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes,BOOL bManualReset,BOOL bInitialState,LPCSTR lpName)
  CreateEventA                  equ 490190h

; CreateFileA(LPCSTR lpFileName,DWORD dwDesiredAccess,DWORD dwShareMode,LPSECURITY_ATTRIBUTES lpSecurityAttributes,DWORD dwCreationDisposition,DWORD dwFlagsAndAttributes,HANDLE hTemplateFile)
  CreateFileA                   equ 490164h

; CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId)
  CreateThread                  equ 49012Ch

; DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
  DeleteCriticalSection         equ 490170h

; DeleteFileA(LPCSTR lpFileName)
  DeleteFileA                   equ 490140h

; EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
  EnterCriticalSection          equ 490184h

; ExitProcess(UINT uExitCode)
  ExitProcess                   equ 490114h

; ExitThread(DWORD dwExitCode)
  ExitThread                    equ 490120h

; FileTimeToLocalFileTime(const FILETIME *lpFileTime,LPFILETIME lpLocalFileTime)
  FileTimeToLocalFileTime       equ 4901F8h

; FileTimeToSystemTime(const FILETIME *lpFileTime,LPSYSTEMTIME lpSystemTime)
  FileTimeToSystemTime          equ 4901F4h

; FindClose(HANDLE hFindFile)
  FindClose                     equ 490144h

; FindFirstFileA(LPCSTR lpFileName,LPWIN32_FIND_DATAA lpFindFileData)
  FindFirstFileA                equ 49014Ch

; FindNextFileA(HANDLE hFindFile,LPWIN32_FIND_DATAA lpFindFileData)
  FindNextFileA                 equ 490148h

; FlushFileBuffers(HANDLE hFile)
  FlushFileBuffers              equ 490090h

; FormatMessageA(DWORD dwFlags,LPCVOID lpSource,DWORD dwMessageId,DWORD dwLanguageId,LPSTR lpBuffer,DWORD nSize,va_list *Arguments)
  FormatMessageA                equ 4901D0h

; FreeEnvironmentStringsA(LPSTR)
  FreeEnvironmentStringsA       equ 4900CCh

; FreeEnvironmentStringsW(LPWSTR)
  FreeEnvironmentStringsW       equ 4900C8h

; FreeLibrary(HMODULE hLibModule)
  FreeLibrary                   equ 4901B0h

; GetACP(void)
  GetACP                        equ 4900E0h

; GetCPInfo(UINT CodePage,LPCPINFO lpCPInfo)
  GetCPInfo                     equ 4900E4h

; GetCommState(HANDLE hFile,LPDCB lpDCB)
  GetCommState                  equ 4901A0h

; GetCommandLineA(void)
  GetCommandLineA               equ 490154h

; GetComputerNameA(LPSTR lpBuffer,LPDWORD nSize)
  GetComputerNameA              equ 490074h

; GetCurrentProcess(void)
  GetCurrentProcess             equ 490058h

; GetCurrentThreadId(void)
  GetCurrentThreadId            equ 490128h

; GetDateFormatA(LCID Locale,DWORD dwFlags,const SYSTEMTIME *lpDate,LPCSTR lpFormat,LPSTR lpDateStr,int cchDate)
  GetDateFormatA                equ 4901F0h

; GetDiskFreeSpaceA(LPCSTR lpRootPathName,LPDWORD lpSectorsPerCluster,LPDWORD lpBytesPerSector,LPDWORD lpNumberOfFreeClusters,LPDWORD lpTotalNumberOfClusters)
  GetDiskFreeSpaceA             equ 4901DCh

; GetDriveTypeA(LPCSTR lpRootPathName)
  GetDriveTypeA                 equ 490158h

; GetEnvironmentStrings(void)
  GetEnvironmentStrings         equ 4900C4h

; GetEnvironmentStringsW(void)
  GetEnvironmentStringsW        equ 4900C0h

; GetEnvironmentVariableA(LPCSTR lpName,LPSTR lpBuffer,DWORD nSize)
  GetEnvironmentVariableA       equ 4900B8h

; GetFileAttributesA(LPCSTR lpFileName)
  GetFileAttributesA            equ 4901FCh

; GetFileSize(HANDLE hFile,LPDWORD lpFileSizeHigh)
  GetFileSize                   equ 490070h

; GetFileType(HANDLE hFile)
  GetFileType                   equ 4900BCh

; GetLastError(void)
  GetLastError                  equ 490150h

; GetLocalTime(LPSYSTEMTIME lpSystemTime)
  GetLocalTime                  equ 490134h

; GetLogicalDriveStringsA(DWORD nBufferLength,LPSTR lpBuffer)
  GetLogicalDriveStringsA       equ 49015Ch

; GetModuleFileNameA(HMODULE hModule,LPSTR lpFilename,DWORD nSize)
  GetModuleFileNameA            equ 49013Ch

; GetModuleHandleA(LPCSTR lpModuleName)
  GetModuleHandleA              equ 4901C0h

; GetOEMCP(void)
  GetOEMCP                      equ 4900DCh

; GetOverlappedResult(HANDLE hFile,LPOVERLAPPED lpOverlapped,LPDWORD lpNumberOfBytesTransferred,BOOL bWait)
  GetOverlappedResult           equ 4901B4h

; GetProcAddress(HMODULE hModule,LPCSTR lpProcName)
  GetProcAddress                equ 490174h

; GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo)
  GetStartupInfoA               equ 49011Ch

; GetStdHandle(DWORD nStdHandle)
  GetStdHandle                  equ 490060h

; GetStringTypeA(LCID Locale,DWORD dwInfoType,LPCSTR lpSrcStr,int cchSrc,LPWORD lpCharType)
  GetStringTypeA                equ 4900A4h

; GetStringTypeW(DWORD dwInfoType,LPCWSTR lpSrcStr,int cchSrc,LPWORD lpCharType)
  GetStringTypeW                equ 4900A0h

; GetSystemInfo(LPSYSTEM_INFO lpSystemInfo)
  GetSystemInfo                 equ 4901E0h

; GetSystemTime(LPSYSTEMTIME lpSystemTime)
  GetSystemTime                 equ 4901ACh

; GetTickCount(void)
  GetTickCount                  equ 490138h

; GetTimeFormatA(LCID Locale,DWORD dwFlags,const SYSTEMTIME *lpTime,LPCSTR lpFormat,LPSTR lpTimeStr,int cchTime)
  GetTimeFormatA                equ 4901ECh

; GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
  GetTimeZoneInformation        equ 4901E4h

; GetVersion(void)
  GetVersion                    equ 490068h

; GetVersionExA(LPOSVERSIONINFOA lpVersionInformation)
  GetVersionExA                 equ 4900B4h

; GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer)
  GlobalMemoryStatus            equ 4901D8h

; HeapAlloc(HANDLE hHeap,DWORD dwFlags,DWORD dwBytes)
  HeapAlloc                     equ 4900ECh

; HeapCreate(DWORD flOptions,DWORD dwInitialSize,DWORD dwMaximumSize)
  HeapCreate                    equ 4900ACh

; HeapDestroy(HANDLE hHeap)
  HeapDestroy                   equ 4900B0h

; HeapFree(HANDLE hHeap,DWORD dwFlags,LPVOID lpMem)
  HeapFree                      equ 490100h

; HeapReAlloc(HANDLE hHeap,DWORD dwFlags,LPVOID lpMem,DWORD dwBytes)
  HeapReAlloc                   equ 4900D8h

; HeapSize(HANDLE hHeap,DWORD dwFlags,LPCVOID lpMem)
  HeapSize                      equ 4900D4h

; InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
  InitializeCriticalSection     equ 49016Ch

; InterlockedDecrement(LPLONG lpAddend)
  InterlockedDecrement          equ 490200h

; InterlockedIncrement(LPLONG lpAddend)
  InterlockedIncrement          equ 490118h

; IsBadReadPtr(const void *lp,UINT ucb)
  IsBadReadPtr                  equ 4901BCh

; IsBadWritePtr(LPVOID lp,UINT ucb)
  IsBadWritePtr                 equ 4901CCh

; LCMapStringA(LCID Locale,DWORD dwMapFlags,LPCSTR lpSrcStr,int cchSrc,LPSTR lpDestStr,int cchDest)
  LCMapStringA                  equ 490108h

; LCMapStringW(LCID Locale,DWORD dwMapFlags,LPCWSTR lpSrcStr,int cchSrc,LPWSTR lpDestStr,int cchDest)
  LCMapStringW                  equ 490104h

; LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
  LeaveCriticalSection          equ 490180h

; LoadLibraryA(LPCSTR lpLibFileName)
  LoadLibraryA                  equ 490178h

; LocalAlloc(UINT uFlags,UINT uBytes)
  LocalAlloc                    equ 490064h

; LocalFree(HLOCAL hMem)
  LocalFree                     equ 4901A8h

; MulDiv(int nNumber,int nNumerator,int nDenominator)
  MulDiv                        equ 4901E8h

; MultiByteToWideChar(UINT CodePage,DWORD dwFlags,LPCSTR lpMultiByteStr,int cchMultiByte,LPWSTR lpWideCharStr,int cchWideChar)
  MultiByteToWideChar           equ 49010Ch

; RaiseException(DWORD dwExceptionCode,DWORD dwExceptionFlags,DWORD nNumberOfArguments,const DWORD *lpArguments)
  RaiseException                equ 49006Ch

; ReadFile(HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped)
  ReadFile                      equ 490198h

; ResetEvent(HANDLE hEvent)
  ResetEvent                    equ 490188h

; SetCommState(HANDLE hFile,LPDCB lpDCB)
  SetCommState                  equ 49019Ch

; SetCommTimeouts(HANDLE hFile,LPCOMMTIMEOUTS lpCommTimeouts)
  SetCommTimeouts               equ 4901A4h

; SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,BOOL Add)
  SetConsoleCtrlHandler         equ 490130h

; SetEndOfFile(HANDLE hFile)
  SetEndOfFile                  equ 49008Ch

; SetEnvironmentVariableA(LPCSTR lpName,LPCSTR lpValue)
  SetEnvironmentVariableA       equ 490080h

; SetEvent(HANDLE hEvent)
  SetEvent                      equ 49017Ch

; SetFileAttributesA(LPCSTR lpFileName,DWORD dwFileAttributes)
  SetFileAttributesA            equ 49007Ch

; SetFilePointer(HANDLE hFile,LONG lDistanceToMove,PLONG lpDistanceToMoveHigh,DWORD dwMoveMethod)
  SetFilePointer                equ 49009Ch

; SetHandleCount(UINT uNumber)
  SetHandleCount                equ 49005Ch

; SetLastError(DWORD dwErrCode)
  SetLastError                  equ 4900F8h

; SetStdHandle(DWORD nStdHandle,HANDLE hHandle)
  SetStdHandle                  equ 490094h

; SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)
  SetUnhandledExceptionFilter   equ 4901D4h

; Sleep(DWORD dwMilliseconds)
  Sleep                         equ 490168h

; TerminateProcess(HANDLE hProcess,UINT uExitCode)
  TerminateProcess              equ 4900E8h

; TlsAlloc(void)
  TlsAlloc                      equ 4900FCh

; TlsGetValue(DWORD dwTlsIndex)
  TlsGetValue                   equ 4900F4h

; TlsSetValue(DWORD dwTlsIndex,LPVOID lpTlsValue)
  TlsSetValue                   equ 490124h

; UnhandledExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
  UnhandledExceptionFilter      equ 4900F0h

; VirtualAlloc(LPVOID lpAddress,DWORD dwSize,DWORD flAllocationType,DWORD flProtect)
  VirtualAlloc                  equ 490098h

; VirtualFree(LPVOID lpAddress,DWORD dwSize,DWORD dwFreeType)
  VirtualFree                   equ 4900A8h

; VirtualQuery(LPCVOID lpAddress,PMEMORY_BASIC_INFORMATION lpBuffer,DWORD dwLength)
  VirtualQuery                  equ 4901C4h

; WaitForMultipleObjects(DWORD nCount,const HANDLE *lpHandles,BOOL bWaitAll,DWORD dwMilliseconds)
  WaitForMultipleObjects        equ 490194h

; WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds)
  WaitForSingleObject           equ 49018Ch

; WideCharToMultiByte(UINT CodePage,DWORD dwFlags,LPCWSTR lpWideCharStr,int cchWideChar,LPSTR lpMultiByteStr,int cchMultiByte,LPCSTR lpDefaultChar,LPBOOL lpUsedDefaultChar)
  WideCharToMultiByte           equ 490110h

; WriteFile(HANDLE hFile,LPCVOID lpBuffer,DWORD nNumberOfBytesToWrite,LPDWORD lpNumberOfBytesWritten,LPOVERLAPPED lpOverlapped)
  WriteFile                     equ 4901B8h

; lstrcpynA(LPSTR lpString1,LPCSTR lpString2,int iMaxLength)
  lstrcpynA                     equ 4901C8h


its gooder to hax hard and NEVER get caught!

Offline iL

  • Administrator
  • Ogre Mage
  • *****
  • Posts: 1653
    • View Profile
Re: Re: War2 100% of 1 core CPU load - CPU Savior, version 2
« Reply #13 on: February 27, 2017, 05:05:54 AM »
Anyway, this is totally the way to go. You can never reliably hard code procedure entry points in external modules. They can be re-mapped by the OS, but in fact almost never are. The other problem is different versions of the same module will shift the entry points for the individual procedures even if the module is mapped at the same base address.
I'd appreciate if you fork my project, fix that and release it as your version somewhere on bitbucket.org or anywhere else. That is my first experince with hooking and it's not perfect. I'd be glad to look into that myself and understand how to fix it, but i absolutely have no time for war2 and for such low-priority projects.
If you fix my code i can build it and distrubute to community and a part of combat or w/e (after some beta-test period to make sure everything works perfect everywhere).
Need help to translate War2Combat to German, French, Italian, Polish or another language: http://forum.war2.ru/index.php/topic,4728.0.html
Please, contact me if you are interested in that.