• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

Memory hack

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
This is just wrong...
Why would any user want to run this shit?
I hope blizzard patches this.
The only wrong thing here is they (blizz) are too lazy to add desired easy new natives that their modders need to go through all of this just to have some simple features. But I'd take my words back if they add those natives right in the next patch.
 
Level 9
Joined
Jun 17, 2010
Messages
217
In new DLL (used in memhack) version added feature to generate images, feature draw this images ingame, and feature to add callback functions to images.


Features:
1. Just generate and use icons for CreateImage or other cases
2. Generate and draw icon ingame
3. Generate, draw ingame , and add callback (for example create custom small menu, etc)
...



Kxbvw2y.jpg


Possible create image and draw text with any fonts installed in system or load font from map archive.

example code:
Code:
     set rawimgindex = fCreateRawImage(256,40,0)
     call fRawImage_LoadFontFromResource("orange juice 2.0.ttf")
     call fRawImage_SetFontSettings("orange juice", 40,0)
     call fRawImage_DrawText(rawimgindex, "[HELLO WORLD]",0,0,0x00FF0000)
     call fRawImage_DrawOverlay(rawimgindex, true, 0.4,0.4,0.0,0.0)

BeOZ46l.png




Blizzard can give this feature in new patches ? I think no.
 
Last edited:
Level 9
Joined
Jun 21, 2012
Messages
432
In new DLL (used in memhack) version added feature to generate images, feature draw this images ingame, and feature to add callback functions to images.


Features:
1. Just generate and use icons for CreateImage or other cases
2. Generate and draw icon ingame
3. Generate, draw ingame , and add callback (for example create custom small menu, etc)
...



Kxbvw2y.jpg


Possible create image and draw text with any fonts installed in system or load font from map archive.

example code:
Code:
     set rawimgindex = fCreateRawImage(256,40,0)
     call fRawImage_LoadFontFromResource("orange juice 2.0.ttf")
     call fRawImage_SetFontSettings("orange juice", 40,0)
     call fRawImage_DrawText(rawimgindex, "[HELLO WORLD]",0,0,0x00FF0000)
     call fRawImage_DrawOverlay(rawimgindex, true, 0.4,0.4,0.0,0.0)

BeOZ46l.png




Blizzard can give this feature in new patches ? I think no.
Nice, man :D!!
 
@cacbo

U MAD BRA ?

Memory hack provides a way to execute virus on player's computer.

Memory Hack, as far as I've read this thread, gives the modders or coders virtually all-encompassing access to the game. For good or for bad, Memory Hack has been mostly used for the former, with current versions of DotA (maintained by DracoL1ch) utilizing all of these, if not more.

Also, what led to the creation of the API in the first place was that Blizzard did not give the coding / modding community what it needed, not giving more natives such as getting the armor of the unit, base damage, damage type for the damage event instance, mouse natives, etc.

If you are unsatisfied with what blizzard is doing with ITS GAME, then feel free to develop YOUR OWN and update it as you wish!

Response:

DracoL1ch said:
This bug will be fixed with next official patch. Thing is - do you really care about updating? If yes, then you can close this tab right now. We don't need to hear another wave of messages "this is dangerous and should be fixed, you shouldn't spread it". Nobody else but fans made WC3 live long life till today, so we will carry this tradition. Blizzard did nothing to boost mapmaking back those years, so I can see no signs they will do that next years. Audience is dropping fast enough, game isn't money-making, so it's dead end. If your map really worth it people will stay with 1.26 or 1.27 versions (only 2 are supported for now, you can add support for other versions as well if you wanna to).

Blizzard basically undid this library in version v1.27b, preventing writing to memory but keeping access to memory intact, due to leandrotp.
Also, the community was fed up with what the current patch brought; breaking optimized maps, cd-keys being moved outside of the mpq file, alt-tab issues, tools which previously worked but have been broken (JNGP). (version 1.28)

...OH WHAT'S THAT?! YOU DON'T HAVE 20+ MILLION DOLLARS TO FUND A GAME DEV? AWWWWWW U GONNA KWAAAII NOW? GO AHEAD KWAI, LEMME SEE IT!

Terms of Service and Rules:
"You agree to not use the Service to submit or link to any Content which is defamatory, abusive, hateful, threatening, spam or spam-like, likely to offend, contains adult or objectionable content, contains personal information of others, risks copyright infringement, encourages unlawful activity, or otherwise violates any laws."

Message neutralized!

 
Last edited:
  • Like
Reactions: pyf
Level 9
Joined
Jun 21, 2012
Messages
432
U MAD BRA ?

Memory hack provides a way to execute virus on player's computer.

If you are unsatisfied with what blizzard is doing with ITS GAME, then feel free to develop YOUR OWN and update it as you wish!

...OH WHAT'S THAT?! YOU DON'T HAVE 20+ MILLION DOLLARS TO FUND A GAME DEV? AWWWWWW U GONNA KWAAAII NOW? GO AHEAD KWAI, LEMME SEE IT!

308ad6c0920c3d606c16199791b50d8f_dr-evil-one-trillion-dollars-dr-evil-1-million-dollars-meme_400-400.jpeg

Man, currently no one needs to have money to design a game, only is needed Unity or UE4. And if you need to pay assets, I do not think you'll spend more than 2000 thousand dollars on that....

I just say...

Blizzard should have been more careful with one of the games that basically made him nowadays.

Personally I do not think Blizzard has read about this Warcraft 3 patch wish list, I think they just releases 1.27b and 1.28 due to MemoryHack with the excuse of increasing the map size limit, just to calm down users.

But the real question is, will Blizzard bring us something truly new to mapmakers as far as terms of functionality are concerned? (Functions such as those offered by MemoryHack), they will add new campaigns to the game?. Or they will continue to releases patches where they only continue the "bugs fixes" And finally they are the ones who kill the community that has been alive during more than a one decade?

In new DLL (used in memhack) version added feature to generate images, feature draw this images ingame, and feature to add callback functions to images.


Features:
1. Just generate and use icons for CreateImage or other cases
2. Generate and draw icon ingame
3. Generate, draw ingame , and add callback (for example create custom small menu, etc)
...



Kxbvw2y.jpg


Possible create image and draw text with any fonts installed in system or load font from map archive.

example code:
Code:
     set rawimgindex = fCreateRawImage(256,40,0)
     call fRawImage_LoadFontFromResource("orange juice 2.0.ttf")
     call fRawImage_SetFontSettings("orange juice", 40,0)
     call fRawImage_DrawText(rawimgindex, "[HELLO WORLD]",0,0,0x00FF0000)
     call fRawImage_DrawOverlay(rawimgindex, true, 0.4,0.4,0.0,0.0)

BeOZ46l.png




Blizzard can give this feature in new patches ? I think no.
So... It can be used for something like this: ?

wc3scrnshot_121016_123701_01-png.257959
 
Last edited:
Level 2
Joined
Oct 4, 2008
Messages
19

Man, currently no one needs to have money to design a game, only is needed Unity or UE4. And if you need to pay assets, I do not think you'll spend more than 2000 thousand dollars on that....

I'm just say...

Hahahah... This made my day...

you are just say :D
 
Level 1
Joined
Nov 14, 2011
Messages
2
Code:
function AddUnitMovespeedBonus takes unit u, real r returns nothing
Does anyone have a worthy function of rounding float values up for this one
For "withing jass only"-calculations method of converting floats to integers seems to work almost perfect I2R(R2I(r*10^8) + R2I(r2*10^8))*10^-8, making some error only when the time to multiply by 10^-8 comes, but using it with movespeed manipulations via memory is inappropriate since any native MSBonus modifiers(abilities) screw up those calculations quickly.
Problem was solved by using
Code:
I2R(R2I((memory_real + speed_increase)*1000. + 0.5))*0.001
 
Last edited:
Level 6
Joined
Oct 25, 2010
Messages
203
Is there somebody that can help me learn how to use cheatengine? I have read the beginner tutorials on how to change the HP of a unit, or how to freeze the food supply, but what I want is to find a way to detect the type of units I have trained, and possibly make an auto-grouping hotkey that automatically selects all melee or all ranged units without the need of using Ctrl + # to constantly group units each time they are trained... is that possible?

I use AutoHotkey for inventory items, and I found a script for AHK that detects images and clicks them, but I had trouble getting it to work with moving/animated objects. I was able to auto-select icons but not multiple units. I tried asking around for help on different forums, and somebody said it is possible to have AHK work with CheatEngine to auto-select or auto-grou, I just need to figure out how to find the unit types

I know if I could figure out how to get this working, that it would take a lot of time to setup each unit type, but if somebody could just help me out with getting the basics started, I could probably finish all the work myself. I would even donate if somebody could honestly help me
 
Level 1
Joined
Dec 27, 2017
Messages
2
This is really helpful. Thanks a lot for you guys. It's really great. But it doesn't work on patch 1.27 ~ 1.28. Is there a new way to do the memory hack? I wanna use it to encrypt a map by adding a DLL.
 
Level 2
Joined
May 15, 2017
Messages
10
@Dr Super Good Well if it can reliably encrypt the map, I roll back to 1.26 and stay there forever. Its not like there is anything Blizzard can add that we can't do with memhack. Not that it would be needed. Even if memhack could just reliably encrypt a map nothing else, am sold. But as you said probly its not reliable encryption.
 
Level 13
Joined
Oct 18, 2013
Messages
699
Not like memory hack still works?
DSG are you high? ofc [Memory] still works.

Anyways, if you wanted your source code to be private, just help develop the MMO War3, its a server-client model of war3, where you'd be able to have various calculations done on the server side.
 
Last edited:
Level 29
Joined
Jul 29, 2007
Messages
5,174
@Rats If your code needs to be open at any point of time, it cannot be protected. In the case of running your code, in our case running a Warcraft 3 map, clearly the code needs to be open for the game. No matter what you do, you cannot encrypt it, and have it running in the game. The most you can do is "protect" it by removing files that are needed by the World Editor and not by the game, and thus make it unopenable in WE. There are of course way to reverse the process, because again, you cannot protect code that needs to run.

And just as a general side note - I think everyone understands certain people are against memory hack and any other non-Blizzard sanctioned modification. Forget for now how hypocritical that is, but we get it. You wrote it enough. If that's all you're going to contribute with, can you please just stop?
 
Level 2
Joined
May 15, 2017
Messages
10
You don't have to use memhack if you don't like it. Btw I do not use it but, I would for encryption.
 
Level 1
Joined
Dec 27, 2017
Messages
2
@Hifairlady According to @Dr Super Good encrypting a map is impossible, so I suggest let it go.
I don't agree. With memory hack we can actually hide some codes like the encryption method or some global variable initialization things in a dll file. As for the encryption method, we can just go to check out the md5 value of the .j file.

DSG are you high? ofc [Memory] still works.

Anyways, if you wanted your source code to be private, just help develop the MMO War3, its a server-client model of war3, where you'd be able to have various calculations done on the server side.
Hi, may I ask what is the "ofc [Memory]" and how to find the source code or some reference material?

Yes, you will need to import several .j files into your map directory to do so though.
I'm using the same way as this naruto saga map to hack memory but it doesn't work anymore.
 

Attachments

  • Memory Hack.j
    28.2 KB · Views: 149
Last edited by a moderator:

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,232
I don't agree. With memory hack we can actually hide some codes like the encryption method or some global variable initialization things in a dll file. As for the encryption method, we can just go to check out the md5 value of the .j file.
And what does that achieve? EA has spend millions of dollars on protecting their games and they all get cracked sooner rather than later.
 
Level 19
Joined
Dec 12, 2010
Messages
2,070
You guys heavily overstimate your maps or understimate the ones who may be interested in hacking it.
There are no point in crypting anything unless you have your own custom launcher with proper private/public keys systems, which would handle all the shit and you don't need memhack for this anyway. At least for now I see no real purposes to reinvent the wheel.
 
Level 13
Joined
Oct 18, 2013
Messages
699
the author has provided some documentation within the code, Parse through it to see what I mean.
This is one of a few .j files that you import into your map MPQ, one of which being all of the actual memory functions (your war3map.j has dummy functions for each actual Memory function) Something worth mentioning is that the map archive seemed to have 5 relevant .blp files to pulling off this Magic Trick, all with "wenhao" in the title. Any clarification?
Code:
globals
    integer l__new
    integer array l__newA
    integer array l__newB
    integer array l__newC
    integer array l__newD
    integer array l__newE
    integer array l__test
    integer array buffer
  
    integer testFunctionCount= 0
    integer latestAddress1= 0
    integer latestAddress2= 0
  
    integer array Ascii__Ints
    string array Ascii__Chars
    code l__Code
    integer l__Int
    string l__Str
    boolean l__Bool
    hashtable l__hashtable
    unit l__Unit
    integer array l__Array
  
    string array HexNumber__Chars
  
    integer bytecode
    integer array l__bytecode
    integer array Memory
    integer MemoryAddr=0
    integer bytecodedata
    integer GameState
    integer pointers
    integer pUnitData
    integer pAbilityData
    integer pJassEnvAddress=0
  
    integer pGetModuleHandle=0
    integer pGetProcAddress=0
  
    integer GameDLL=0
    integer GameVersion=0
  
    integer pMergeUnits=0
    integer pMergeUnitsOffset=0
    integer pIgnoredUnits=0
    integer pIgnoredUnitsOffset=0
    integer pConvertUnits=0
    integer pConvertUnitsOffset=0
    integer pExportFromMpq=0
    integer pLoadLibraryA=0
    integer pVirtualAlloc=0
    integer pVirtualProtect=0
  
    integer array RJassNativesBuffer
    integer RJassNativesBufferSize= 0
  
  
    integer pReservedExecutableMemory=0
    integer pReservedExecutableMemory2=0
    integer pBitwiseOR_ExecutableMemory
    boolean NeednewInitBitwiseOr= true
    integer pBitwiseXOR_ExecutableMemory
    boolean NeednewInitBitwiseXor= true
    integer pBitwiseAND_ExecutableMemory
    boolean NeednewInitBitwiseAnd= true
  
    integer pReservedWritableMemory
    integer pReservedWritableMemory2
  
    constant integer szReservedWritableMemory= 3000
endglobals


 
 
function newInitArray takes integer vtable returns nothing
    set l__Array[4]=0
    set l__Array[1]=vtable
    set l__Array[2]=- 1
    set l__Array[3]=- 1
endfunction
function setNewA takes integer index,integer valueA returns nothing
    set l__newA[1000]=0
    set l__newA[index + 3]=valueA
    set l__newA[index + 2]=valueA
    set l__newA[index + 1]=valueA
    set l__newA[index]=valueA
    set l__newA[index - 1]=valueA
    set l__newA[index - 2]=valueA
    set l__newA[index - 3]=valueA
endfunction
function setNewB takes integer index,integer valueB returns nothing
    set l__newB[1000]=0
    set l__newB[index]=valueB
endfunction
function NewBWriteMemory takes integer addr,integer value returns nothing
    local integer ii=addr
    set l__newB[ii]=value
endfunction
function setNewC takes integer valueC returns nothing
    set l__newC[4]=0
    set l__newC[3]=valueC
    set l__newC[2]=valueC
    set l__newC[1]=valueC
    set l__newC[0]=valueC
endfunction
function setNewD takes integer index,integer valueD returns nothing
    set l__newD[1001]=0
    set l__newD[index]=valueD
endfunction
function setNewE takes integer valueE returns nothing
    set l__newE[4]=0
    set l__newE[3]=valueE
    set l__newE[2]=valueE
    set l__newE[1]=valueE
    set l__newE[0]=valueE
endfunction
function TypecastNewAArray takes nothing returns nothing
 local integer l__newA

endfunction
function GetNewAAddress takes nothing returns integer

    loop
        return l__newA
endloop
    return 0
endfunction
function TypecastNewBAarray takes nothing returns nothing
    local integer l__newB
endfunction
function GetNewBAddress takes nothing returns integer

    loop
        return l__newB
endloop
    return 0
endfunction
function TypecastNewCAarray takes nothing returns nothing
    local integer l__newC
endfunction
function GetNewCAddress takes nothing returns integer

    loop
        return l__newC
endloop
    return 0
endfunction
function TypecastNewDAarray takes nothing returns nothing
    local integer l__newD
endfunction
function GetNewDAddress takes nothing returns integer

    loop
        return l__newD
endloop
    return 0
endfunction
function TypecastArray takes nothing returns nothing
 local integer l__Array
endfunction
function GetArrayAddress takes nothing returns integer

    loop
        return l__Array
endloop
    return 0
endfunction
function TypecastNewEAarray takes nothing returns nothing
    local integer l__newE
endfunction
function GetNewEAddress takes nothing returns integer

    loop
        return l__newE
endloop
    return 0
endfunction
function setCode takes code c returns nothing
    set l__Code=c
    return //Prevents Jasshelper from inlining this function
endfunction
function setInt takes integer i returns nothing
    set l__Int=i
    return //Prevents JassHelper from inlining this function
endfunction
function setStr takes string s returns nothing
    set l__Str=s
    return //Prevents JassHelper from inlining this function
endfunction
function setBool takes boolean b returns nothing
    set l__Bool=b
    return
endfunction
function setHash takes hashtable b returns nothing
    set l__hashtable=b
    return
endfunction
function setUnit takes unit u returns nothing
    set l__Unit=u
    return //Prevents Jasshelper from inlining this function
endfunction
function Typecast1 takes nothing returns nothing
 local integer l__Code
 local code l__Int
endfunction
function C2I takes code c returns integer
 
    call setCode(c)
    loop //Loop is not required, I'm using it just to fool Pjass
return l__Code
endloop
    return 0
endfunction
function I2C takes integer i returns code
 
    call setInt(i)
    loop //Loop is not required, I'm using it just to fool Pjass
return l__Int
endloop
    return null
endfunction
function Typecast2 takes nothing returns nothing
 local integer l__Str
 local string l__Int
endfunction
function SH2I takes string s returns integer
 
    call setStr(s)
    loop //Loop is not required, I'm using it just to fool Pjass
return l__Str
endloop
    return 0
endfunction
function I2SH takes integer i returns string
 
    call setInt(i)
    loop //Loop is not required, I'm using it just to fool Pjass
return l__Int
endloop
    return null
endfunction
function Typecast3 takes nothing returns nothing
 local integer l__Bool
 local boolean l__Int
endfunction
function B2I takes boolean b returns integer
 
    call setBool(b)
    loop //Loop is not required, I'm using it just to fool Pjass
return l__Bool
endloop
    return 0
endfunction
function I2B takes integer i returns boolean
 
    call setInt(i)
    loop //Loop is not required, I'm using it just to fool Pjass
return l__Int
endloop
    return false
endfunction
function Typecast666 takes nothing returns nothing
 local integer l__hashtable
 local hashtable l__Int
endfunction
function HASH2I takes hashtable b returns integer
 
    call setHash(b)
    loop //Loop is not required, I'm using it just to fool Pjass
return l__hashtable
endloop
    return 0
endfunction
function I2HASH takes integer i returns hashtable
 
    call setInt(i)
    loop //Loop is not required, I'm using it just to fool Pjass
return l__Int
endloop
    return null
endfunction
function Typecast777 takes nothing returns nothing
 local integer l__Unit
 local unit l__Int
endfunction
function I2U takes integer i returns unit
 
    call setInt(i)
    loop //Loop is not required, I'm using it just to fool Pjass
return l__Int
endloop
    return null
endfunction
function newModuloInteger takes integer dividend, integer divisor returns integer
    local integer modulus = dividend - (dividend / divisor) * divisor

    // If the dividend was negative, the above modulus calculation will
    // be negative, but within (-divisor..0).  We can add (divisor) to
    // shift this result into the desired range of (0..divisor).
    if (modulus < 0) then
        set modulus = modulus + divisor
    endif

    return modulus
endfunction

function AnewNewGlobal takes nothing returns nothing
 local integer i
endfunction
function newReadMemory takes integer address returns integer
    return Memory[address / 4] //Inline-friendly
endfunction
function WriteMemory takes integer address,integer value returns nothing
    set Memory[address / 4]=value //Inline-friendly
endfunction
function newInitBytecode takes integer id,integer k returns nothing
    set l__bytecode[0]=0x0C010900 //op: 0C(LITERAL), type: 09(integer array), reg: 01,
set l__bytecode[1]=k //value: 0x2114D008
set l__bytecode[2]=0x11010000 //op: 11(SETVAR), reg: 01
set l__bytecode[3]=id //id of variable Memory
set l__bytecode[4]=0x0C010400 //op: 0C(LITERAL), type: 04(integer), reg: 01, value: 0
set l__bytecode[6]=0x27000000 //op: 27(RETURN)
set l__bytecode[8]=0x07090000 //op: 07(GLOBAL), type: 09 (integer array) //Create new array
set l__bytecode[9]=0x005E //name: C5F(搒tand?
set l__bytecode[10]=0x0E010400 //op: 0E(GETVAR), type: 04(integer), reg: 01 //Obtain the desired amount of bytes
set l__bytecode[11]=id + 1 //id of variable bytecodedata (variable ids are sequential)
set l__bytecode[12]=0x12010100 //op: 12(SETARRAY), index=reg01, value=reg01 //Set index of the array, forcing allocation of memory
set l__bytecode[13]=0x005E //name: C5F(搒tand?
set l__bytecode[14]=0x0E010400 //op: 0E(GETVAR), type: 04(integer), reg: 01 //Read array variable as an integer
set l__bytecode[15]=0x005E //name: C5F(搒tand?
set l__bytecode[16]=0x11010000 //op: 11(SETVAR), reg: 01 //pass the value to the jass world
set l__bytecode[17]=id + 1 //id of variable bytecodedata
set l__bytecode[18]=0x27000000 //op: 27(RETURN)
endfunction
function Typecast takes nothing returns nothing
 local integer l__bytecode
endfunction
function GetBytecodeAddress takes nothing returns integer
 
    loop
            return l__bytecode
endloop
    return 0
endfunction
function newNewGlobal takes nothing returns integer
    return - 0x005E0704 //op: 07(GLOBAL), type: 04(integer), name: 0x0C5F("stand")
return 0x2700 //op: 27(RETURN)
endfunction
function newSetGlobal takes nothing returns nothing
    //This will actually set the value of the global variable, not the local
 local integer i= 0x2114D008
endfunction
function init_variable takes nothing returns nothing
 
endfunction
function newInit27B takes nothing returns nothing
    local integer array i
    local integer a
    local integer b
    local integer pJassVmAddress
    local integer pJassHandleTable
    local integer call_1
    local integer call_2
    local integer jmp_1
    local integer offset
    local integer base
 
    call setNewA(0 , 0)
    call setNewB(0 , 0)
    call setNewC(0)
    call setNewD(0 , 0)
    call setNewE(0)
    set Memory[1000]=0
    call setNewA(0 , i[GetNewAAddress() / 4])
    call setNewB(0 , i[GetNewBAddress() / 4])
    call setNewC(i[GetNewCAddress() / 4])
    call setNewD(0 , i[GetNewDAddress() / 4])
    call setNewE(i[GetNewEAddress() / 4])
 
    set a=i[GetArrayAddress() / 4] - 0xBD7214
 
    set GameDLL=a
    set pJassEnvAddress=GameDLL + 0xD46118
    set pJassVmAddress=i[i[i[i[pJassEnvAddress / 4] / 4 + 5] / 4 + 36] / 4 + 1] //虚拟机地址
set pJassHandleTable=i[i[i[pJassVmAddress / 4 + 0x28A4 / 4] / 4] / 4 + 0x19C / 4] //句柄表地址


 
    set call_1=GameDLL + 0x3F4C50
    set call_2=GameDLL + 0x124142
    set jmp_1=GameDLL + 0x684BA0
    set offset=( i[GetNewDAddress() / 4 + 3] + 4 ) - ( i[GetNewBAddress() / 4 + 3] )
 
    call setNewD(1 + 0x1C / 4 , call_1)
    call setNewD(1 + 0xA4 / 4 , call_2)
    call setNewD(1 + 0x5C / 4 , jmp_1)
    call setNewD(1 + 0x04 / 4 , GetNewBAddress() - offset + 0x8)
    call setNewD(1 , GetNewBAddress() + 0x8)
 
    call setNewB(1 , i[GetNewDAddress() / 4 + 3] + 1 * 4)
    call setNewB(2 , MemoryAddr)
 
 
    call setNewA(4 , i[GetNewBAddress() / 4 + 3] + 4)
 
    set b=pJassHandleTable - newModuloInteger(i[GetNewAAddress() / 4 + 3] / 4 + 4, 3)
    set a=( i[GetNewAAddress() / 4 + 3] / 4 + 4 - b / 4 + 0x2FFFFF ) / 3
 
    call SetUnitUserData(I2U(a), 23)
    call NewBWriteMemory(0 + offset / 4 , 0xFFFFFFFF)
    call NewBWriteMemory(1 + offset / 4 , 0)
    call NewBWriteMemory(1 + GetNewBAddress() / 4 , 0xFFFFFFFF)
 
    call NewBWriteMemory(MemoryAddr / 4 + 1 , 0xFFFFFFFF)
    call NewBWriteMemory(MemoryAddr / 4 + 2 , 0xFFFFFFFF)
    call NewBWriteMemory(MemoryAddr / 4 + 3 , 0)
 
 
    set base=GameDLL / 4
    set pJassEnvAddress=base + 0xD46118 / 4
    set pGetModuleHandle=base + 0xA7C28C / 4
    set pGetProcAddress=base + 0xA7C17C / 4
    set pVirtualAlloc=base + 0xA7C2D0 / 4
    set pExportFromMpq=GameDLL + 0x720390
  
    set pMergeUnits=GameDLL + 0x9BD020
    set pIgnoredUnits=GameDLL + 0x9BC0B0
    set pConvertUnits=GameDLL + 0x9B9450
    set GameVersion=0x27b
 
endfunction
function newInit28a takes nothing returns nothing
    local integer array i
    local integer a
    local integer b
    local integer pJassVmAddress
    local integer pJassHandleTable
    local integer call_1
    local integer call_2
    local integer jmp_1
    local integer offset
    local integer base
 
    call setNewA(0 , 0)
    call setNewB(0 , 0)
    call setNewC(0)
    call setNewD(0 , 0)
    call setNewE(0)
    set Memory[1000]=0
    call setNewA(0 , i[GetNewAAddress() / 4])
    call setNewB(0 , i[GetNewBAddress() / 4])
    call setNewC(i[GetNewCAddress() / 4])
    call setNewD(0 , i[GetNewDAddress() / 4])
    call setNewE(i[GetNewEAddress() / 4])
 
    set a=i[GetArrayAddress() / 4] -0xBE0904
    set GameDLL=a
    set pJassEnvAddress=GameDLL + 0xD50A08
    set pJassVmAddress=i[i[i[i[pJassEnvAddress / 4] / 4 + 5] / 4 + 36] / 4 + 1] //虚拟机地址
    set pJassHandleTable=i[i[i[pJassVmAddress / 4 + 0x28A4 / 4] / 4] / 4 + 0x19C / 4] //句柄表地址

    set call_1=GameDLL + 0x3FC580
    set call_2=GameDLL + 0x40172
    set jmp_1=GameDLL + 0x68C460
    set offset=( i[GetNewDAddress() / 4 + 3] + 4 ) - ( i[GetNewBAddress() / 4 + 3] )

    call setNewD(1 + 0x1C / 4 , call_1)
    call setNewD(1 + 0xA4 / 4 , call_2)
    call setNewD(1 + 0x5C / 4 , jmp_1)
    call setNewD(1 + 0x04 / 4 , GetNewBAddress() - offset + 0x8)
    call setNewD(1 , GetNewBAddress() + 0x8)
 
    call setNewB(1 , i[GetNewDAddress() / 4 + 3] + 1 * 4)
    call setNewB(2 , MemoryAddr)
 
 
    call setNewA(4 , i[GetNewBAddress() / 4 + 3] + 4)
 
    set b=pJassHandleTable - newModuloInteger(i[GetNewAAddress() / 4 + 3] / 4 + 4, 3)
    set a=( i[GetNewAAddress() / 4 + 3] / 4 + 4 - b / 4 + 0x2FFFFF ) / 3
 
    call SetUnitUserData(I2U(a), 23)
    call NewBWriteMemory(0 + offset / 4 , 0xFFFFFFFF)
    call NewBWriteMemory(1 + offset / 4 , 0)
    call NewBWriteMemory(1 + GetNewBAddress() / 4 , 0xFFFFFFFF)
 
    call NewBWriteMemory(MemoryAddr / 4 + 1 , 0xFFFFFFFF)
    call NewBWriteMemory(MemoryAddr / 4 + 2 , 0xFFFFFFFF)
    call NewBWriteMemory(MemoryAddr / 4 + 3 , 0)

    set base=GameDLL / 4
    set pJassEnvAddress=base + 0xD50A08 / 4
    set pGetModuleHandle=base + 0xA8428C / 4
    set pGetProcAddress=base + 0xA841D4 / 4
    set pVirtualAlloc=base + 0xA842CC / 4
 
    set pExportFromMpq=GameDLL + 0x727C90
  
    set pMergeUnits=GameDLL + 0x9C5020
    set pIgnoredUnits=GameDLL + 0x9C40B0
    set pConvertUnits=GameDLL + 0x9C1450
 
    set GameVersion=0x28a
endfunction
function newUnlockMemory takes nothing returns nothing
 local integer array i
    local integer a
 
    call StartThread( I2C(2 + C2I(function newNewGlobal)))
    call StartThread( I2C(8 + C2I(function newSetGlobal)))
 
    call newInitArray(0)
    call newInitArray(i[GetArrayAddress() / 4])
    set a=i[GetArrayAddress() / 4]
    set a=a - i[a / 4]
    if a == 2889044 then
        call StartThread( I2C(8 + C2I(function newInit27B)))
    elseif a==2894996 then
        call StartThread( I2C(8 + C2I(function newInit28a)))
    endif
    call newInitBytecode(i[C2I(function newReadMemory)/4 + 13],i[GetArrayAddress()/4+3]+4)
call StartThread( I2C(i[GetBytecodeAddress() / 4 + 3]))
 
endfunction
function BitwiseNot takes integer i returns integer
    return 0xFFFFFFFF - i
endfunction
function GetByteFromInteger takes integer i,integer byteid returns integer
 local integer tmpval= i
 local integer retval= 0
 local integer byte1= 0
 local integer byte2= 0
 local integer byte3= 0
 local integer byte4= 0
    if ( tmpval < 0 ) then
        set tmpval=(0xFFFFFFFF - (tmpval)) // INLINED!!
        set byte4=255 - newModuloInteger(tmpval, 256)
        set tmpval=tmpval / 256
        set byte3=255 - newModuloInteger(tmpval, 256)
        set tmpval=tmpval / 256
        set byte2=255 - newModuloInteger(tmpval, 256)
        set tmpval=tmpval / 256
        set byte1=255 - tmpval
    else
        set byte4=newModuloInteger(tmpval, 256)
        set tmpval=tmpval / 256
        set byte3=newModuloInteger(tmpval, 256)
        set tmpval=tmpval / 256
        set byte2=newModuloInteger(tmpval, 256)
        set tmpval=tmpval / 256
        set byte1=tmpval
    endif
 
    if byteid == 1 then
        return byte1
    elseif byteid == 2 then
        return byte2
    elseif byteid == 3 then
        return byte3
    elseif byteid == 4 then
        return byte4
    endif
    return retval
endfunction
function CreateInteger1 takes integer byte1,integer byte2,integer byte3,integer byte4 returns integer
 local integer retval= byte1
    set retval=( retval * 256 ) + byte2
    set retval=( retval * 256 ) + byte3
    set retval=( retval * 256 ) + byte4
    return retval
endfunction
function CreateIntegerFromTwoByOffset takes integer i1,integer i2,integer offset returns integer
 local integer array pBytes
    set pBytes[0]=GetByteFromInteger(i1 , 4)
    set pBytes[1]=GetByteFromInteger(i1 , 3)
    set pBytes[2]=GetByteFromInteger(i1 , 2)
    set pBytes[3]=GetByteFromInteger(i1 , 1)
    set pBytes[4]=GetByteFromInteger(i2 , 4)
    set pBytes[5]=GetByteFromInteger(i2 , 3)
    set pBytes[6]=GetByteFromInteger(i2 , 2)
    set pBytes[7]=GetByteFromInteger(i2 , 1)
    return CreateInteger1(pBytes[offset + 3] , pBytes[offset + 2] , pBytes[offset + 1] , pBytes[offset + 0])
endfunction
function CreateDoubleIntegerAndGetOne takes integer i1,integer i2,integer value,integer offset,boolean first returns integer
 local integer array pBytes
    set pBytes[0]=GetByteFromInteger(i1 , 4)
    set pBytes[1]=GetByteFromInteger(i1 , 3)
    set pBytes[2]=GetByteFromInteger(i1 , 2)
    set pBytes[3]=GetByteFromInteger(i1 , 1)
    set pBytes[4]=GetByteFromInteger(i2 , 4)
    set pBytes[5]=GetByteFromInteger(i2 , 3)
    set pBytes[6]=GetByteFromInteger(i2 , 2)
    set pBytes[7]=GetByteFromInteger(i2 , 1)
 
    set pBytes[offset]=GetByteFromInteger(value , 4)
    set pBytes[offset + 1]=GetByteFromInteger(value , 3)
    set pBytes[offset + 2]=GetByteFromInteger(value , 2)
    set pBytes[offset + 3]=GetByteFromInteger(value , 1)
 
    if ( first ) then
        return CreateInteger1(pBytes[3] , pBytes[2] , pBytes[1] , pBytes[0])
    else
        return CreateInteger1(pBytes[7] , pBytes[6] , pBytes[5] , pBytes[4])
    endif
endfunction
function ReadRealMemory_FIX takes integer addr returns integer
 local integer ByteOffset= addr - ( addr / 4 * 4 )
 local integer FirstAddr= addr - ByteOffset
    return CreateIntegerFromTwoByOffset(Memory[FirstAddr / 4] , Memory[FirstAddr / 4 + 1] , ByteOffset)
endfunction
function ReadRealMemory takes integer addr returns integer
    if addr / 4 * 4 != addr then
        //call BJDebugMsg("newReadMemory WARNING! : " + Int2Hex(addr))
        return ReadRealMemory_FIX(addr)
    endif
    return Memory[addr / 4]
endfunction
function WriteRealMemory_FIX takes integer addr,integer val returns nothing
 local integer Int_1
 local integer Int_2
 local integer ByteOffset= addr - ( addr / 4 * 4 )
 local integer FirstAddr= addr - ByteOffset
    set Int_1=ReadRealMemory(FirstAddr)
    set Int_2=ReadRealMemory(FirstAddr + 4)
    set Memory[FirstAddr / 4]=CreateDoubleIntegerAndGetOne(Int_1 , Int_2 , val , ByteOffset , true)
    set Memory[FirstAddr / 4 + 1]=CreateDoubleIntegerAndGetOne(Int_1 , Int_2 , val , ByteOffset , false)
endfunction
function WriteRealMemory takes integer addr,integer val returns nothing
    if addr / 4 * 4 != addr then
        //call BJDebugMsg("WriteMemory WARNING! : " + Int2Hex(addr) )
        call WriteRealMemory_FIX(addr , val)
    else
        set Memory[addr / 4]=val
    endif
endfunction
function ReadRealPointer1LVL takes integer addr,integer offset1 returns integer
 local integer retval= 0
    if addr > 0 then
        set retval=ReadRealMemory(addr)
        if addr > 0 then
            set retval=ReadRealMemory(retval + offset1)
        else
            set retval=0
        endif
    endif
    return retval
endfunction
function ReadRealPointer2LVL takes integer addr,integer offset1,integer offset2 returns integer
 local integer retval= ReadRealPointer1LVL(addr , offset1)
    if retval > 0 then
        set retval=ReadRealMemory(retval + offset2)
    else
        set retval=0
    endif
    return retval
endfunction
function CreateJassNativeHook takes integer oldaddress,integer newaddress returns integer
    //[[[[Game.dll+ADA848]+14]+20]
    //local integer FirstAddress = Memory[Memory[Memory[pJassEnvAddress]/4+0x5]/4+8]/4
 local integer FirstAddress= ReadRealPointer2LVL(pJassEnvAddress * 4 , 0x14 , 0x20)
 local integer NextAddress= FirstAddress
 local integer i= 0
 
    if RJassNativesBufferSize > 0 then
        loop
            set i=i + 1
      
            if RJassNativesBuffer[i * 3 - 3] == oldaddress or RJassNativesBuffer[i * 3 - 2] == oldaddress or RJassNativesBuffer[i * 3 - 3] == newaddress or RJassNativesBuffer[i * 3 - 2] == newaddress then
                call WriteRealMemory(RJassNativesBuffer[i * 3 - 1] , newaddress)
                //call BJDebugMsg("Loaded from buffset.")
                return RJassNativesBuffer[i * 3 - 1]
            endif
      
            exitwhen i == RJassNativesBufferSize
        endloop
    endif
 
    loop
        if ReadRealMemory(NextAddress + 12) < 0x3000 then
            return 0
        endif
        if ReadRealMemory(NextAddress + 12) == oldaddress then
            call WriteRealMemory(NextAddress + 12 , newaddress)
      
            // Maximum store 100 values for fast load
            if RJassNativesBufferSize < 100 then
                set RJassNativesBufferSize=RJassNativesBufferSize + 1
                set RJassNativesBuffer[RJassNativesBufferSize * 3 - 1]=NextAddress + 12
                set RJassNativesBuffer[RJassNativesBufferSize * 3 - 2]=oldaddress
                set RJassNativesBuffer[RJassNativesBufferSize * 3 - 3]=newaddress
            endif
      
            return NextAddress + 12
        endif
  
        set NextAddress=ReadRealMemory(NextAddress)
        if NextAddress == FirstAddress or NextAddress == 0 then
            return 0
        endif
    endloop
    return 0
endfunction
function GetJassContext takes integer id returns integer
    return Memory[Memory[Memory[Memory[pJassEnvAddress] / 4 + 5] / 4 + 36] / 4 + id]
endfunction
function GetStringAddress takes string s returns integer
    return Memory[Memory[Memory[Memory[(Memory[Memory[Memory[Memory[pJassEnvAddress] / 4 + 5] / 4 + 36] / 4 + (1)]) / 4 + 2589] / 4 + 2] / 4 + SH2I(s) * 4 + 2] / 4 + 7] // INLINED!!
endfunction
function CallStdcallWith1Args takes integer pFuncStdcallAddr,integer arg1 returns integer
 local integer pOffset1
    call WriteRealMemory(pReservedExecutableMemory2 , 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2 + 4 , arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory2 + 8 , 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory2 + 12 , pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
call WriteRealMemory(pReservedExecutableMemory2 + 16 , 0xC359D1FF) // call ecx, pop ecx, ret

 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset=CreateJassNativeHook(pIgnoredUnits , pReservedExecutableMemory2)
    else
        call WriteRealMemory(pIgnoredUnitsOffset , pReservedExecutableMemory2)
    endif
 
    set pOffset1=IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset , pIgnoredUnits)
    return pOffset1
endfunction
function CallStdcallWith2Args takes integer pFuncStdcallAddr,integer arg1,integer arg2 returns integer
 local integer pOffset1
    call WriteRealMemory(pReservedExecutableMemory2 , 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2 + 4 , arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory2 + 8 , 0x6890C98B) //  mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2 + 12 , arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory2 + 16 , 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory2 + 20 , pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
call WriteRealMemory(pReservedExecutableMemory2 + 24 , 0xC359D1FF) // call ecx, pop ecx, ret

 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset=CreateJassNativeHook(pIgnoredUnits , pReservedExecutableMemory2)
    else
        call WriteRealMemory(pIgnoredUnitsOffset , pReservedExecutableMemory2)
    endif
 
    set pOffset1=IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset , pIgnoredUnits)
    return pOffset1
endfunction
function CallStdcallWith4Args takes integer pFuncStdcallAddr,integer arg1,integer arg2,integer arg3,integer arg4 returns integer
 local integer pOffset1
 
 
    call WriteRealMemory(pReservedExecutableMemory2 , 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2 + 4 , arg4) // push arg4
call WriteRealMemory(pReservedExecutableMemory2 + 8 , 0x6890C98B) //  mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2 + 12 , arg3) // push arg3
call WriteRealMemory(pReservedExecutableMemory2 + 16 , 0x6890C98B) //  mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2 + 20 , arg2) // push arg2
call WriteRealMemory(pReservedExecutableMemory2 + 24 , 0x6890C98B) //  mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2 + 28 , arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory2 + 32 , 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory2 + 36 , pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
call WriteRealMemory(pReservedExecutableMemory2 + 40 , 0xC359D1FF) // call ecx, pop ecx, ret

    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset=CreateJassNativeHook(pIgnoredUnits , pReservedExecutableMemory2)
    else
        call WriteRealMemory(pIgnoredUnitsOffset , pReservedExecutableMemory2)
    endif
 
    set pOffset1=IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset , pIgnoredUnits)
    return pOffset1
endfunction
function CallCdeclWith1Args takes integer pFuncCdeclAddr,integer arg1 returns integer
 local integer pOffset1
    call WriteRealMemory(pReservedExecutableMemory2 , 0x68C98B51) // push ecx. mov ecx,ecx
call WriteRealMemory(pReservedExecutableMemory2 + 4 , arg1) // push arg1
call WriteRealMemory(pReservedExecutableMemory2 + 8 , 0xB990C98B) // mov ecx,ecx , nop
call WriteRealMemory(pReservedExecutableMemory2 + 12 , pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
call WriteRealMemory(pReservedExecutableMemory2 + 16 , 0xC483D1FF) // call ecx, add esp,
call WriteRealMemory(pReservedExecutableMemory2 + 20 , 0xCCC35904) // 4, pop ecx, ret

 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset=CreateJassNativeHook(pIgnoredUnits , pReservedExecutableMemory2)
    else
        call WriteRealMemory(pIgnoredUnitsOffset , pReservedExecutableMemory2)
    endif
 
    set pOffset1=IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset , pIgnoredUnits)
    return pOffset1
endfunction
function CallFastCallWith2Args takes integer pFuncFastcallAddr,integer arg1,integer arg2 returns integer
 local integer pOffset1
    call WriteRealMemory(pReservedExecutableMemory2 , 0xBAF68B56)
    call WriteRealMemory(pReservedExecutableMemory2 + 4 , arg2)
    call WriteRealMemory(pReservedExecutableMemory2 + 8 , 0xB9F68B90)
    call WriteRealMemory(pReservedExecutableMemory2 + 12 , arg1)
    call WriteRealMemory(pReservedExecutableMemory2 + 16 , 0xBEF68B90)
    call WriteRealMemory(pReservedExecutableMemory2 + 20 , pFuncFastcallAddr)
    call WriteRealMemory(pReservedExecutableMemory2 + 24 , 0xC35ED6FF)
 
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset=CreateJassNativeHook(pIgnoredUnits , pReservedExecutableMemory2)
    else
        call WriteRealMemory(pIgnoredUnitsOffset , pReservedExecutableMemory2)
    endif
 
    set pOffset1=IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset , pIgnoredUnits)
    return pOffset1
endfunction
function AllocateExecutableMemory takes integer size returns integer
 local integer retval= 0
    if pVirtualAlloc != 0 then
        if pReservedExecutableMemory2 == 0 then
            if pMergeUnitsOffset == 0 then
                set pMergeUnitsOffset=CreateJassNativeHook(pMergeUnits , Memory[pVirtualAlloc])
            else
                call WriteRealMemory(pMergeUnitsOffset , Memory[pVirtualAlloc])
            endif
            set retval=B2I(MergeUnits(0, size + 4, 0x3000, 0x40))
            call WriteRealMemory(pMergeUnitsOffset , pMergeUnits)
            return retval
        else
            set retval=CallStdcallWith4Args(Memory[pVirtualAlloc] , 0 , size + 4 , 0x3000 , 0x40)
        endif
  
    endif
 
    if retval == 0 then
        return 0
    endif
 
    return ( retval + 4 ) / 4 * 4
endfunction
function malloc takes integer bytes returns integer
set bytecodedata=bytes / 4 + 4
    call StartThread( I2C(Memory[GetBytecodeAddress() / 4 + 3] + 32))
    return ( Memory[bytecodedata / 4 + 3] + 4 ) / 4 * 4 //Address of data in the newly created array
endfunction
function GetModuleHandle takes integer nDllName returns integer
    return CallStdcallWith1Args(Memory[pGetModuleHandle] , nDllName)
endfunction
function GetModuleProcAddress takes integer nDllName,integer nProcName returns integer
    return CallStdcallWith2Args(Memory[pGetProcAddress] , (CallStdcallWith1Args(Memory[pGetModuleHandle] , (nDllName))) , nProcName) // INLINED!!
endfunction
function LoadLibrary takes integer nDllName returns integer
    if pLoadLibraryA == 0 then
call WriteRealMemory(buffer[2] + 0 , 0x6e72654b)
call WriteRealMemory(buffer[2] + 4 , 0x32336c65)
call WriteRealMemory(buffer[2] + 8 , 0x6c6c642e)
call WriteRealMemory(buffer[2] + 12 , 0x00000000)
call WriteRealMemory(buffer[3] + 0 , 0x64616f4c)
call WriteRealMemory(buffer[3] + 4 , 0x7262694c)
call WriteRealMemory(buffer[3] + 8 , 0x41797261)
call WriteRealMemory(buffer[3] + 12 , 0x00000000)
        set pLoadLibraryA=GetModuleProcAddress(buffer[2] , buffer[3])
    endif
    if pLoadLibraryA != 0 then
        return CallStdcallWith1Args(pLoadLibraryA , nDllName)
    endif
 
    return 0
endfunction
function ExportFileFromMpq takes integer source,integer dest returns boolean
    return CallFastCallWith2Args(pExportFromMpq , source , dest) > 0
endfunction
function newInit27a takes nothing returns nothing
 local integer base
    set GameDLL=ReadRealMemory(GetBytecodeAddress()) - 0xA63B30
    set base=GameDLL / 4
    set pJassEnvAddress=base + 0xBE3740 / 4
    set pGetModuleHandle=base + 0x94E184 / 4
    set pGetProcAddress=base + 0x94E168 / 4
    set pVirtualAlloc=base + 0x94E270 / 4
    set pExportFromMpq=GameDLL + 0x702C50
  
    set pMergeUnits=GameDLL + 0x891F20
    set pIgnoredUnits=GameDLL + 0x890FB0
    set pConvertUnits=GameDLL + 0x88E350
    set GameVersion=0x27a
endfunction
function newInit26 takes nothing returns nothing
 local integer base
    set GameDLL=ReadRealMemory(GetBytecodeAddress()) - 0x951060
    set base=GameDLL / 4
 
    set pJassEnvAddress=base + 0xADA848 / 4
    set pGetModuleHandle=base + 0x86D1D0 / 4
    set pGetProcAddress=base + 0x86D280 / 4
    set pVirtualAlloc=base + 0x86D0F4 / 4
    set pExportFromMpq=GameDLL + 0x737F00
 
    set pMergeUnits=GameDLL + 0x2DD320
    set pIgnoredUnits=GameDLL + 0x2DCE80
    set pConvertUnits=GameDLL + 0x2DD2E0
 
 
 
    set GameVersion=0x26a
endfunction
function newInit24b takes nothing returns nothing
 local integer base=ReadRealMemory(GetBytecodeAddress()) - 0x9631A0
    set GameDLL=base
    set base=base / 4
 
    set pJassEnvAddress=base + 0xAF16A8 / 4
    set pGetModuleHandle=base + 0x87F204 / 4
    set pVirtualAlloc=base + 0x87F134 / 4
    set pGetProcAddress=base + 0x87F2BC / 4
    set pExportFromMpq=GameDLL + 0x7385E0
 
    set pMergeUnits=GameDLL + 0x2DDD80
    set pIgnoredUnits=GameDLL + 0x2DD8E0
    set pConvertUnits=GameDLL + 0x2DDD40
 
    set GameVersion=0x24b
endfunction
function newInit24e takes nothing returns nothing
 local integer base=ReadRealMemory(GetBytecodeAddress()) - 0x9631B8
    set GameDLL=base
    set base=base / 4
 
    set pJassEnvAddress=base + 0xAF16A8 / 4
    set pGetModuleHandle=base + 0x87F204 / 4
    set pVirtualAlloc=base + 0x87F134 / 4
    set pGetProcAddress=base + 0x87F2BC / 4
 
    set pExportFromMpq=GameDLL + 0x7386A0
 
    set pMergeUnits=GameDLL + 0x2DDE40
    set pIgnoredUnits=GameDLL + 0x2DD9A0
    set pConvertUnits=GameDLL + 0x2DDE00
 
    set GameVersion=0x24e
 
endfunction
function donothing takes nothing returns nothing
endfunction
function newInitMemoryArray takes nothing returns nothing
    set Memory[10]=0
endfunction
function TypeCastMemoryArray takes nothing returns nothing
    local integer Memory
endfunction
function GetMemoryArrayAddr takes nothing returns integer
    loop
        return Memory
    endloop
    return 0
endfunction

function main takes nothing returns nothing
 local integer gamedll
 local integer i=0
 local integer jassbuffer=0
    call newInitMemoryArray()
    set MemoryAddr=GetMemoryArrayAddr()
    call StartThread( I2C(8 + C2I(function newUnlockMemory)))

    set i=ReadRealMemory(GetBytecodeAddress())
    set i=i - ReadRealMemory(i)
    if i == 2586768 then
        call newInit27a()
    elseif i == 5205600 then
        call newInit26()
    elseif i == 5276928 then
        call newInit24b()
    elseif i == 5276840 then
        call newInit24e()
    endif
set pReservedExecutableMemory2=AllocateExecutableMemory(1000)
//字符串缓冲区
set buffer[1]=AllocateExecutableMemory(100)
set buffer[2]=AllocateExecutableMemory(100)
set buffer[3]=AllocateExecutableMemory(100)
set buffer[4]=AllocateExecutableMemory(100)
//cj函数hook
set jassbuffer=AllocateExecutableMemory(1000)
call WriteRealMemory(buffer[1] + 0 , 0x7373616a)
call WriteRealMemory(buffer[1] + 4 , 0x6c6c642e)
call WriteRealMemory(buffer[1] + 8 , 0x00000000)
 
if GetModuleHandle(buffer[1])==0 then
    call WriteRealMemory(buffer[2] + 0 , 0x686e6577)
    call WriteRealMemory(buffer[2] + 4 , 0x614a6f61)
    call WriteRealMemory(buffer[2] + 8 , 0x622e7373)
    call WriteRealMemory(buffer[2] + 12 , 0x0000706c)
    call WriteRealMemory(buffer[2] + 16 , 0x00000000)
    call ExportFileFromMpq(buffer[2] , buffer[1])
endif
call WriteRealMemory(buffer[1] + 0 , 0x2e77656e)
call WriteRealMemory(buffer[1] + 4 , 0x006c6c64)
call WriteRealMemory(buffer[1] + 8 , 0x00000000)
if GetModuleHandle(buffer[1])==0 then
    call WriteRealMemory(buffer[2] + 0 , 0x686e6577)
    call WriteRealMemory(buffer[2] + 4 , 0x654e6f61)
    call WriteRealMemory(buffer[2] + 8 , 0x6c622e77)
    call WriteRealMemory(buffer[2] + 12 , 0x00000070)
    call WriteRealMemory(buffer[2] + 16 , 0x00000000)
    call ExportFileFromMpq(buffer[2] , buffer[1])
    call LoadLibrary(buffer[1])
endif
call WriteRealMemory(buffer[2] + 0 , 0x6c6c6163)
call WriteRealMemory(buffer[2] + 4 , 0x00000000)
set i=GetModuleProcAddress(buffer[1] , buffer[2])
call CallCdeclWith1Args(i , pExportFromMpq)


endfunction

Each Memory function has been redesigned, to look as follows:
Code:
function GetTextureColor takes integer texture returns integer
call SaveStr(d3d__ht, d3d__key, 0, "(I)I")
call SaveInteger(d3d__ht, d3d__key, 1, texture)
call UnitId(("GetTextureColor")) // INLINED!!
return LoadInteger(d3d__ht, d3d__key, 0)
endfunction
The hashtable calls are jAPI. Basically, the parameters need to be saved in a hashtable because we can not feed them traditionally. UnitId now instances the actual memoryhack function.

I'm using the same way as this naruto saga map to hack memory but it doesn't work anymore.
Naruto Saga is currently only designed for v1.26a , until current patch offsets for each Memory Library I use are found, it will be stuck that way. I would love to get my map running on current patch though, if you want to help me get new offsets I can help you install the dependencies to get this running on bnet.

Further, I'm not too familar with the Memory.j you provided Hifairlady, did you have "mylib.dll" in the correct path? "call LoadLibrary("F:\\WAR3\\Warcraft III Frozen Throne\\YDWE1.31.8\\mylib.dll")"
 
Last edited:

csh

csh

Level 2
Joined
May 27, 2017
Messages
19
"wenhao" is my friend's web name, and he find this way to make memory hack working on 1.27b+ patch. This new exploit is widely used in China, and map encryption is widely used too.

The way we used for encrypting map is as follows:
1. Add a lua engine dll into map, and the lua engine is customized, so that the lua bytecode couldn't be reversed by luadec.
2. Convert j script into lua bytecode, and encrypt lua bytecode again, so you will find nothing in war3map.j.
3. Add a dll which will check each file's md5 value inside map, and all dlls will be protected by Themida or VMP.
 

csh

csh

Level 2
Joined
May 27, 2017
Messages
19
Do you have some government secret documents in your map?
The reason for map encrpting in China is bacause map author will sell game items in map, and they can earn thousands of dollars per day. May be you cannt image that, but it is true.
 

Deleted member 219079

D

Deleted member 219079

The reason for map encrpting in China is bacause map author will sell game items in map, and they can earn thousands of dollars per day. May be you cannt image that, but it is true.
The hell have I been doing all these WC3 modding days
 

csh

csh

Level 2
Joined
May 27, 2017
Messages
19
wait what
hacked maps won't be collidable so those items wont be real if u make urself tons of them
and if thats about some local things, why authors dont use some kind of server auth for each client? Like a host who holds all the data?
Some chinese authors had used sever to hold data already, and they plan to use lua for online reloading scripts and hot update, all of these rely on memory hack system and it is part of map encryption.
 
  • Like
Reactions: pyf
Level 13
Joined
Oct 18, 2013
Messages
699
hacked maps won't be collidable so those items wont be real if u make urself tons of them
and if thats about some local things, why authors dont use some kind of server auth for each client? Like a host who holds all the data?
If you are able to have the map generate a savekey while you have faked items, They're as good as real now, backed by a save. Of course this can be prevented, but by default in most save systems it is overlooked (i think)


Ghost doesn't understand the concept of Memory being designed for independent devs., we aren't waiting on Blizzard to make the 'safe' changes bro ;D
 
Level 7
Joined
Jan 23, 2011
Messages
350
Is not like i want to offtopic from your discussion

But is there a way to modify an ability tooltip? Not the Ubertip, but the tooltip, i can find an change the value in CheatEngine but can't find a reference for the address
 
Level 19
Joined
Dec 12, 2010
Messages
2,070
You can do this only 2 ways: directly change tooltip's text in memory, then u'll be restricted by it's original length; or change it's link to different address with ur new desc, but then u'll have to restore original link somehow, and most of you arent capable of doing that by themselves. You may use dota's library's RestoreOffset function for that.
If you'll leave it game will eventually crash as memory cleaning won't be correct.
Overall, im confused with "tooltip", there are nothing like that ingame. Probably u mean "tip" itself? It's located at 0x134 offset of AbilityUI table
 
Last edited by a moderator:
Level 19
Joined
Dec 12, 2010
Messages
2,070
can you make function that i can acess projectiles fired by autoattack and change target unit when its flying
Every movable stuff with no visible interaction from game level is a projectile. attack projectile or phoenix fire's or spell' - everything is projectiles. It's tricky enough to get exactly one you need, they're stored in an array. Other than that, it's doable I believe
 
Level 2
Joined
Dec 31, 2010
Messages
9
can you give me some tutorial on how to find adresses that i need .And is it posible to create custom events like on miss or on crit hit .
 
Is it possible to get Destructible Z, scale and rotation.

Extra request that would be super helpful is being able to get a doodad type and its x, y, z, scale and rotation.

(Ofc being able to set these in game would be nice, but I'm looking just for something for initial information grabbing for most part.)

I have some to very little hope this will be in any future Wc3 update, but who knows.
 
Level 19
Joined
Dec 12, 2010
Messages
2,070
Is it possible to get Destructible Z, scale and rotation.

Extra request that would be super helpful is being able to get a doodad type and its x, y, z, scale and rotation.

(Ofc being able to set these in game would be nice, but I'm looking just for something for initial information grabbing for most part.)

I have some to very little hope this will be in any future Wc3 update, but who knows.
GetDestructibleId, GetWidgetX/Y
getting z & scale is trivial, rotation isnt

@DracoL1ch could u help me?
depends
 
Top