, ,

[RenderEdge] Memory Hack

» опубликован

Актуальная версия v1.0.1a

Описание

Теперь можно редактировать стандартный интерфейс Варкрафта без необходимости внедрять сторонние библиотеки.
Требования:

Код

» Typecast
native MergeUnits	takes integer qty, integer a, integer b, integer make returns boolean
native ConvertUnits takes integer qty, integer id returns boolean
native IgnoredUnits takes integer unitid returns integer

library Typecast

    globals
        code Code //This is not used, it's here just to fool Jasshelper
        code l__Code
        integer Int //This is not used, it's here just to fool Jasshelper
        integer l__Int
        string Str //This is not used, it's here just to fool Jasshelper
        string l__Str
        boolean Bool //This is not used, it's here just to fool Jasshelper
        boolean l__Bool
        
        integer Array
        integer array l__Array
        integer bytecode
        integer array l__bytecode
        integer array Memory
        integer bytecodedata //used to pass data between regular code and bytecode
    endglobals

    function InitArray 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 TypecastArray takes nothing returns nothing
        local integer Array //typecast Array to integer
    endfunction

    //# +nosemanticerror
    function GetArrayAddress takes nothing returns integer //not really needed
        return l__Array
        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 //Prevents Jasshelper from inlining this function
    endfunction

    private function Typecast1 takes nothing returns nothing
        local integer Code //Jasshelper will implicitly rename this to l__Code
        local code Int     //Jasshelper will implicitly rename this to l__Int
    endfunction

    //# +nosemanticerror
    function C2I takes code c returns integer
        call setCode(c)
        return l__Code
    endfunction

    //# +nosemanticerror
    function I2C takes integer i returns code
        call setInt(i)
        return l__Int
    endfunction

    private function Typecast2 takes nothing returns nothing
        local integer Str //Jasshelper will implicitly rename this to l__Str
        local string Int   //Jasshelper will implicitly rename this to l__Int
    endfunction

    //# +nosemanticerror
    function SH2I takes string s returns integer
        call setStr(s)
        return l__Str
    endfunction

    //# +nosemanticerror
    function I2SH takes integer i returns string
        call setInt(i)
        return l__Int
    endfunction

    private function Typecast3 takes nothing returns nothing
        local integer Bool //Jasshelper will implicitly rename this to l__Bool
        local boolean Int  //Jasshelper will implicitly rename this to l__Int
    endfunction

    //# +nosemanticerror
    function B2I takes boolean b returns integer
        call setBool(b)
        return l__Bool
    endfunction

    //# +nosemanticerror
    function I2B takes integer i returns boolean
        call setInt(i)
        return l__Int
    endfunction

    //# +nosemanticerror
    function realToIndex takes real r returns integer
        return r
    endfunction

    function cleanInt takes integer i returns integer
        return i
    endfunction

    //# +nosemanticerror
    function indexToReal takes integer i returns real
        return i
    endfunction

    function cleanReal takes real r returns real
        return r
    endfunction

    function ReadMemory 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 InitBytecode 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 udg_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] = 0x0C5F 		//name: C5F(?stand?)
        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 udg_Memory
        set l__bytecode[13] = 0x0C5F 		//name: C5F(?stand?)
        set l__bytecode[14] = 0x0E010400 	//op: 0E(GETVAR), type: 04(integer), reg: 01 //Read array variable as an integer
        set l__bytecode[15] = 0x0C5F 		//name: C5F(?stand?)
        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 bytecode
    endfunction

    //# +nosemanticerror
    function GetBytecodeAddress takes nothing returns integer
        return l__bytecode
        return 0
    endfunction

    function NewGlobal takes nothing returns integer
        return -0x0C5F0704 //op: 07(GLOBAL), type: 04(integer), name: 0x0C5F("stand")
        return 0x2700 //op: 27(RETURN)
    endfunction

    function SetGlobal takes nothing returns nothing
        //This will actually set the value of the global variable, not the local
        local integer stand = 0x2114D008
    endfunction

    //# +nosemanticerror
    function UnlockMemory takes nothing returns nothing
        local integer array stand //The execution of this line is skipped
        call ForForce(bj_FORCE_PLAYER[0], I2C(2+C2I(function NewGlobal)))
        call ForForce(bj_FORCE_PLAYER[0], I2C(8+C2I(function SetGlobal)))
        call InitArray( 0 )
        call InitArray(stand[GetArrayAddress()/4])
        call InitBytecode(stand[C2I(function ReadMemory)/4 + 13], stand[GetArrayAddress()/4+3]+4) //obtain the id of variable "Memory"
        call ForForce(bj_FORCE_PLAYER[0], I2C(stand[GetBytecodeAddress()/4+3])) //run bytecode from the array
    endfunction

    function ReadRealMemory takes integer addr returns integer
        if (addr/4*4 != addr) then
            call BJDebugMsg("ReadMemory WARNING!")
            //return ReadRealMemory_FIX(addr)
        endif
        return Memory[addr/4]
    endfunction

    function WriteRealMemory takes integer addr, integer val returns nothing
        if (addr/4*4 != addr) then
            call BJDebugMsg("WriteMemory WARNING!")
            //call WriteRealMemory_FIX(addr,val)
        else
            set Memory[addr/4] = val
        endif
    endfunction

endlibrary
» MemoryHack
library MemoryHack initializer Init uses Typecast

    globals
        integer pVirtualAlloc = 0
        integer pJassEnvAddress = 0
        integer array RJassNativesBuffer
        integer RJassNativesBufferSize = 0
        integer pIgnoredUnits = 0
        integer pIgnoredUnitsOffset = 0
        integer pMergeUnits = 0
        integer pMergeUnitsOffset = 0
        
        integer GameDLL
        integer GameState
    endglobals

    
    private function InitAddresses takes nothing returns nothing
        set GameState = (GameDLL + 0xAB65F4) / 4
        set pJassEnvAddress = (GameDLL + 0xADA848) / 4
        set pVirtualAlloc = (GameDLL + 0x86D0F4) / 4
        set pMergeUnits = GameDLL + 0x2DD320
        set pIgnoredUnits = GameDLL + 0x2DCE80
    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[GetJassContext(1)/4 + 2589]/4 + 2]/4 + SH2I(s)*4 + 2]/4 + 7]
    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
        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)
                    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)
                
                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

    
    private function Init takes nothing returns nothing
        local integer i
        call ForForce(bj_FORCE_PLAYER[0], I2C(8+C2I(function UnlockMemory)))
        set i = Memory[GetBytecodeAddress()/4]
        set i = i - Memory[i/4]
        
        if i == 5205600 then // 1.26a
            set GameDLL = ReadRealMemory(GetBytecodeAddress()) - 0x951060
            call InitAddresses()
        else
            call BJDebugMsg("Unsupported version!")
        endif
    endfunction

endlibrary
» FpCall
library FpCall initializer Init uses MemoryHack

    globals
        //integer pReservedExecutableMemory0 = 0
        integer pReservedExecutableMemory = 0
    endglobals

    
    function fast_call1 takes integer pFuncFastcallAddr, integer arg1 returns integer 
        local integer pOffset1

        call WriteRealMemory(pReservedExecutableMemory, 0xB9F68B56) 
        call WriteRealMemory(pReservedExecutableMemory+4, arg1)
        call WriteRealMemory(pReservedExecutableMemory+8, 0xBEF68B90) 
        call WriteRealMemory(pReservedExecutableMemory+12, pFuncFastcallAddr)
        call WriteRealMemory(pReservedExecutableMemory+16, 0xC35ED6FF)
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction

    function fast_call2 takes integer pFuncFastcallAddr, integer arg1, integer arg2 returns integer 
        local integer pOffset1

        call WriteRealMemory(pReservedExecutableMemory, 0xBAF68B56) 
        call WriteRealMemory(pReservedExecutableMemory+4, arg2)
        call WriteRealMemory(pReservedExecutableMemory+8, 0xB9F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+12, arg1)
        call WriteRealMemory(pReservedExecutableMemory+16, 0xBEF68B90)
        call WriteRealMemory(pReservedExecutableMemory+20, pFuncFastcallAddr)
        call WriteRealMemory(pReservedExecutableMemory+24, 0xC35ED6FF)
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction
    
    function fast_call3 takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 returns integer 
        local integer pOffset1

        call WriteRealMemory(pReservedExecutableMemory, 0x68F68B56) 
        call WriteRealMemory(pReservedExecutableMemory+4, arg3)
        call WriteRealMemory(pReservedExecutableMemory+8, 0xBAF68B90) 
        call WriteRealMemory(pReservedExecutableMemory+12, arg2)
        call WriteRealMemory(pReservedExecutableMemory+16, 0xB9F68B90)
        call WriteRealMemory(pReservedExecutableMemory+20, arg1)
        call WriteRealMemory(pReservedExecutableMemory+24, 0xBEF68B90)
        call WriteRealMemory(pReservedExecutableMemory+28, pFuncFastcallAddr)
        call WriteRealMemory(pReservedExecutableMemory+32, 0xC35ED6FF)
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction
    
    function fast_call4 takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4 returns integer 
        local integer pOffset1

        call WriteRealMemory(pReservedExecutableMemory, 0x68F68B56) 
        call WriteRealMemory(pReservedExecutableMemory+4, arg4)
        call WriteRealMemory(pReservedExecutableMemory+8, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+12, arg3)
        call WriteRealMemory(pReservedExecutableMemory+16, 0xBAF68B90) 
        call WriteRealMemory(pReservedExecutableMemory+20, arg2)
        call WriteRealMemory(pReservedExecutableMemory+24, 0xB9F68B90)
        call WriteRealMemory(pReservedExecutableMemory+28, arg1)
        call WriteRealMemory(pReservedExecutableMemory+32, 0xBEF68B90)
        call WriteRealMemory(pReservedExecutableMemory+36, pFuncFastcallAddr)
        call WriteRealMemory(pReservedExecutableMemory+40, 0xC35ED6FF)
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction
    
    function fast_call5 takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 returns integer 
        local integer pOffset1

        call WriteRealMemory(pReservedExecutableMemory, 0x68F68B56) 
        call WriteRealMemory(pReservedExecutableMemory+4, arg5)
        call WriteRealMemory(pReservedExecutableMemory+8, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+12, arg4)
        call WriteRealMemory(pReservedExecutableMemory+16, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+20, arg3)
        call WriteRealMemory(pReservedExecutableMemory+24, 0xBAF68B90) 
        call WriteRealMemory(pReservedExecutableMemory+28, arg2)
        call WriteRealMemory(pReservedExecutableMemory+32, 0xB9F68B90)
        call WriteRealMemory(pReservedExecutableMemory+36, arg1)
        call WriteRealMemory(pReservedExecutableMemory+40, 0xBEF68B90)
        call WriteRealMemory(pReservedExecutableMemory+44, pFuncFastcallAddr)
        call WriteRealMemory(pReservedExecutableMemory+48, 0xC35ED6FF)
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction
    
    function fast_call6 takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5, integer arg6 returns integer 
        local integer pOffset1

        call WriteRealMemory(pReservedExecutableMemory, 0x68F68B56) 
        call WriteRealMemory(pReservedExecutableMemory+4, arg6)
        call WriteRealMemory(pReservedExecutableMemory+8, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+12, arg5)
        call WriteRealMemory(pReservedExecutableMemory+16, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+20, arg4)
        call WriteRealMemory(pReservedExecutableMemory+24, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+28, arg3)
        call WriteRealMemory(pReservedExecutableMemory+32, 0xBAF68B90) 
        call WriteRealMemory(pReservedExecutableMemory+36, arg2)
        call WriteRealMemory(pReservedExecutableMemory+40, 0xB9F68B90)
        call WriteRealMemory(pReservedExecutableMemory+44, arg1)
        call WriteRealMemory(pReservedExecutableMemory+48, 0xBEF68B90)
        call WriteRealMemory(pReservedExecutableMemory+52, pFuncFastcallAddr)
        call WriteRealMemory(pReservedExecutableMemory+56, 0xC35ED6FF)
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction
    
    function fast_call7 takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5, integer arg6, integer arg7 returns integer 
        local integer pOffset1

        call WriteRealMemory(pReservedExecutableMemory, 0x68F68B56) 
        call WriteRealMemory(pReservedExecutableMemory+4, arg7)
        call WriteRealMemory(pReservedExecutableMemory+8, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+12, arg6)
        call WriteRealMemory(pReservedExecutableMemory+16, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+20, arg5)
        call WriteRealMemory(pReservedExecutableMemory+24, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+28, arg4)
        call WriteRealMemory(pReservedExecutableMemory+32, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+36, arg3)
        call WriteRealMemory(pReservedExecutableMemory+40, 0xBAF68B90) 
        call WriteRealMemory(pReservedExecutableMemory+44, arg2)
        call WriteRealMemory(pReservedExecutableMemory+48, 0xB9F68B90)
        call WriteRealMemory(pReservedExecutableMemory+52, arg1)
        call WriteRealMemory(pReservedExecutableMemory+56, 0xBEF68B90)
        call WriteRealMemory(pReservedExecutableMemory+60, pFuncFastcallAddr)
        call WriteRealMemory(pReservedExecutableMemory+64, 0xC35ED6FF)
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction
    
    function fast_call8 takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5, integer arg6, integer arg7, integer arg8 returns integer 
        local integer pOffset1

        call WriteRealMemory(pReservedExecutableMemory, 0x68F68B56) 
        call WriteRealMemory(pReservedExecutableMemory+4, arg8)
        call WriteRealMemory(pReservedExecutableMemory+8, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+12, arg7)
        call WriteRealMemory(pReservedExecutableMemory+16, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+20, arg6)
        call WriteRealMemory(pReservedExecutableMemory+24, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+28, arg5)
        call WriteRealMemory(pReservedExecutableMemory+32, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+36, arg4)
        call WriteRealMemory(pReservedExecutableMemory+40, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+44, arg3)
        call WriteRealMemory(pReservedExecutableMemory+48, 0xBAF68B90) 
        call WriteRealMemory(pReservedExecutableMemory+52, arg2)
        call WriteRealMemory(pReservedExecutableMemory+56, 0xB9F68B90)
        call WriteRealMemory(pReservedExecutableMemory+60, arg1)
        call WriteRealMemory(pReservedExecutableMemory+64, 0xBEF68B90)
        call WriteRealMemory(pReservedExecutableMemory+68, pFuncFastcallAddr)
        call WriteRealMemory(pReservedExecutableMemory+72, 0xC35ED6FF)
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset, pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction

    
    function this_call1 takes integer pFuncThiscallAddr, integer arg1 returns integer 
        return fast_call2(pFuncThiscallAddr, arg1, 0)
    endfunction
    
    function this_call2 takes integer pFuncThiscallAddr, integer arg1, integer arg2 returns integer 
        return fast_call3(pFuncThiscallAddr, arg1, 0, arg2)
    endfunction
    
    function this_call3 takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3 returns integer 
        return fast_call4(pFuncThiscallAddr, arg1, 0, arg2, arg3)
    endfunction
    
    function this_call4 takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4 returns integer 
        return fast_call5(pFuncThiscallAddr, arg1, 0, arg2, arg3, arg4)
    endfunction
    
    function this_call5 takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4, integer arg5 returns integer 
        return fast_call6(pFuncThiscallAddr, arg1, 0, arg2, arg3, arg4, arg5)
    endfunction
    
    function this_call6 takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4, integer arg5, integer arg6 returns integer 
        return fast_call7(pFuncThiscallAddr, arg1, 0, arg2, arg3, arg4, arg5, arg6)
    endfunction
    
    function this_call7 takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4, integer arg5, integer arg6, integer arg7 returns integer 
        return fast_call8(pFuncThiscallAddr, arg1, 0, arg2, arg3, arg4, arg5, arg6, arg7)
    endfunction


    function std_call1 takes integer pFuncStdcallAddr, integer arg1 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+8, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+12, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
        call WriteRealMemory(pReservedExecutableMemory+16, 0xC359D1FF) // call ecx, pop ecx, ret
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction
    
    function std_call2 takes integer pFuncStdcallAddr, integer arg1, integer arg2 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+16, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+20, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
        call WriteRealMemory(pReservedExecutableMemory+24, 0xC359D1FF) // call ecx, pop ecx, ret
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction
    
    function std_call3 takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg3) // push arg3
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+20, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+24, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+28, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
        call WriteRealMemory(pReservedExecutableMemory+32, 0xC359D1FF) // call ecx, pop ecx, ret
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction
    
    function std_call4 takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg4) // push arg4
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg3) // push arg3
        call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+20, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+24, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+28, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+32, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+36, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
        call WriteRealMemory(pReservedExecutableMemory+40, 0xC359D1FF) // call ecx, pop ecx, ret
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction
    
    function std_call5 takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 returns integer 
        local integer pOffset1
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg5) // push arg5
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg4) // push arg4
        call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+20, arg3) // push arg3
        call WriteRealMemory(pReservedExecutableMemory+24, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+28, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+32, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+36, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+40, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+44, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
        call WriteRealMemory(pReservedExecutableMemory+48, 0xC359D1FF) // call ecx, pop ecx, ret
        
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction
    
    function std_call6 takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 , integer arg6 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg6) // push arg6
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg5) // push arg5
        call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+20, arg4) // push arg4
        call WriteRealMemory(pReservedExecutableMemory+24, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+28, arg3) // push arg3
        call WriteRealMemory(pReservedExecutableMemory+32, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+36, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+40, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+44, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+48, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+52, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
        call WriteRealMemory(pReservedExecutableMemory+56, 0xC359D1FF) // call ecx, pop ecx, ret
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction
    
    
    function c_call1 takes integer pFuncCdeclAddr, integer arg1 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+8, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+12, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
        call WriteRealMemory(pReservedExecutableMemory+16, 0xC483D1FF) // call ecx, add esp, 
        call WriteRealMemory(pReservedExecutableMemory+20, 0xCCC35904) // 4, pop ecx, ret
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction
    
    function c_call2 takes integer pFuncCdeclAddr, integer arg1, integer arg2 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+16, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+20, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
        call WriteRealMemory(pReservedExecutableMemory+24, 0xC483D1FF) // call ecx, add esp, 
        call WriteRealMemory(pReservedExecutableMemory+28, 0xCCC35908) // 4, pop ecx, ret
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction
    
    function c_call3 takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg3) // push arg3
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+20, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+24, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+28, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
        call WriteRealMemory(pReservedExecutableMemory+32, 0xC483D1FF) // call ecx, add esp, 
        call WriteRealMemory(pReservedExecutableMemory+36, 0xCCC3590C) // 4, pop ecx, ret
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction
    
    function c_call4 takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 , integer arg4 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg4) // push arg4
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg3) // push arg3
        call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+20, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+24, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+28, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+32, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+36, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
        call WriteRealMemory(pReservedExecutableMemory+40, 0xC483D1FF) // call ecx, add esp, 
        call WriteRealMemory(pReservedExecutableMemory+44, 0xCCC35910) // 4, pop ecx, ret
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction
    
    function c_call5 takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg5) // push arg5
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg4) // push arg4
        call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+20, arg3) // push arg3
        call WriteRealMemory(pReservedExecutableMemory+24, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+28, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+32, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+36, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+40, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+44, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
        call WriteRealMemory(pReservedExecutableMemory+48, 0xC483D1FF) // call ecx, add esp, 
        call WriteRealMemory(pReservedExecutableMemory+52, 0xCCC35914) // 4, pop ecx, ret
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
        return pOffset1
    endfunction
    
    function c_call6 takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 , integer arg6 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg6) // push arg6
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg5) // push arg5
        call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+20, arg4) // push arg4
        call WriteRealMemory(pReservedExecutableMemory+24, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+28, arg3) // push arg3
        call WriteRealMemory(pReservedExecutableMemory+32, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+36, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+40, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+44, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+48, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+52, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
        call WriteRealMemory(pReservedExecutableMemory+56, 0xC483D1FF) // call ecx, add esp, 
        call WriteRealMemory(pReservedExecutableMemory+60, 0xCCC35918) // 4, pop ecx, ret
        
        if pIgnoredUnitsOffset == 0 then 
            set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
        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 pReservedExecutableMemory == 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 = std_call4(Memory[pVirtualAlloc], 0, size+4, 0x3000, 0x40)
            endif 
            
        endif
        
        if (retval == 0) then 
            return 0
        endif
        
        return (retval + 4) / 4 * 4
    endfunction
    
    
    private function Init takes nothing returns nothing
        //set pReservedExecutableMemory0 = AllocateExecutableMemory(1000)
        set pReservedExecutableMemory = AllocateExecutableMemory(1000)
    endfunction

endlibrary
» Interface
library Interface initializer Init uses FpCall

    globals
        constant integer FRAME_TOPLEFT = 0
        constant integer FRAME_TOP = 1
        constant integer FRAME_TOPRIGHT = 2
        constant integer FRAME_LEFT = 3
        constant integer FRAME_CENTER = 4
        constant integer FRAME_RIGHT = 5
        constant integer FRAME_BOTTOMLEFT = 6
        constant integer FRAME_BOTTOM = 7
        constant integer FRAME_BOTTOMRIGHT = 8
    
        integer address_GetGameUI = 0
        integer address_SetFramePoint = 0
        integer address_SetFramePoint2 = 0
        integer address_SetFrameWidth = 0
        integer address_SetFrameHeight = 0
    endglobals
    
    
    function GetGameUI takes integer a1, integer a2 returns integer
        return fast_call2(address_GetGameUI, a1, a2)
    endfunction
    
    function ReadGameUIArray takes integer element returns integer
        return Memory[GetGameUI(0, 0)/4 + element]
    endfunction
    
    function SetFramePoint takes integer pFrame, integer point, integer pParentFrame, integer relativePoint, real offsetX, real offsetY returns nothing
        call this_call7(address_SetFramePoint, pFrame, point, pParentFrame, relativePoint, cleanInt(realToIndex(offsetX)), cleanInt(realToIndex(offsetY)), 1)
    endfunction
    
    function SetFramePoint2 takes integer pFrame, integer point, real offsetX, real offsetY returns nothing
        call this_call5(address_SetFramePoint2, pFrame, point, cleanInt(realToIndex(offsetX)), cleanInt(realToIndex(offsetY)), 1)
    endfunction
    
    function SetFrameWidth takes integer pFrame, real width returns nothing
        call this_call2(address_SetFrameWidth, pFrame, cleanInt(realToIndex(width)))
    endfunction
    
    function SetFrameHeight takes integer pFrame, real height returns nothing
        call this_call2(address_SetFrameHeight, pFrame, cleanInt(realToIndex(height)))
    endfunction


    function SetBlackBorders takes real upper, real bottom returns nothing
        local integer pBordersFrame = ReadGameUIArray(239) + 180
        local integer pWindowFrame = GetGameUI(0, 0) + 180

        call SetFramePoint(pBordersFrame, FRAME_TOPRIGHT, pWindowFrame, FRAME_TOPRIGHT, 0.0, upper)
        call SetFramePoint(pBordersFrame, FRAME_BOTTOMLEFT, pWindowFrame, FRAME_BOTTOMLEFT, 0.0, bottom)
    endfunction
    
    function SetPortrait takes real offsetX, real offsetY, real width, real height returns nothing
        local integer pPortraitFrame = ReadGameUIArray(253) + 180
        local integer pParentFrame = ReadGameUIArray(265) + 180

        call SetFrameWidth(pPortraitFrame, width)
        call SetFrameHeight(pPortraitFrame, height)
        call SetFramePoint(pPortraitFrame, FRAME_BOTTOMLEFT, pParentFrame, FRAME_BOTTOMLEFT, offsetX, 0.6 - (offsetY + height))
    endfunction

    function SetMinimap takes real x, real y, real width, real height returns nothing
        local integer pMinimapFrame = ReadGameUIArray(240) + 180
        local integer pParentFrame = ReadGameUIArray(263) + 180

        call SetFramePoint(pMinimapFrame, FRAME_BOTTOMLEFT, pParentFrame, FRAME_BOTTOMLEFT, x, 0.6 - y - height)
        call SetFramePoint(pMinimapFrame, FRAME_TOPRIGHT, pParentFrame, FRAME_BOTTOMLEFT, x + width, 0.6 - y)
    endfunction
    
    
    private function Init takes nothing returns nothing
        set address_GetGameUI = GameDLL + 0x300710
        set address_SetFramePoint = GameDLL + 0x606770
        set address_SetFramePoint2 = GameDLL + 0x6061B0
		set address_SetFrameWidth = GameDLL + 0x605D90
		set address_SetFrameHeight = GameDLL + 0x605DB0
    endfunction
    
endlibrary
» InjectDLL
library InjectDLL initializer Init uses FpCall

    globals
        integer pGetModuleHandle = 0
        integer pGetProcAddress = 0
        integer pGetFileAttributesA = 0
        integer pExportFromMpq = 0
        integer pLoadLibraryA = 0
    endglobals


    function GetModuleHandle takes string nDllName returns integer
        return std_call1(Memory[pGetModuleHandle], GetStringAddress(nDllName))
    endfunction

    function GetModuleProcAddress takes string nDllName, string nProcName returns integer
        return std_call2(Memory[pGetProcAddress], GetModuleHandle(nDllName), GetStringAddress(nProcName))
    endfunction
    
    function GetFileAttributes takes string s returns integer
        if pGetFileAttributesA == 0 then
            set pGetFileAttributesA = GetModuleProcAddress("Kernel32.dll", "GetFileAttributesA")
        endif
        if pGetFileAttributesA != 0 then 
            return std_call1(pGetFileAttributesA, GetStringAddress(s))
        endif
        
        return 0
    endfunction
    
    function FileExists takes string s returns boolean
        return (GetFileAttributes(s) != -1)
    endfunction

    function LoadLibrary takes string nDllName returns integer
        if (pLoadLibraryA == 0) then
            set pLoadLibraryA = GetModuleProcAddress("Kernel32.dll", "LoadLibraryA")
            return std_call1(pLoadLibraryA, GetStringAddress(nDllName))
        else
            return std_call1(pLoadLibraryA, GetStringAddress(nDllName))
        endif
        
        return 0
    endfunction

    function ExportFileFromMpq takes string source, string dest returns boolean
        return (fast_call2(pExportFromMpq, GetStringAddress(source), GetStringAddress(dest)) > 0)
    endfunction

    function ExportDllFromMpqAndInjectToWarcraft takes string source, string dest returns boolean
        if (not ExportFileFromMpq(source, dest)) then
            return false
        endif
        
        if (LoadLibrary(dest) == 0) then
            return false
        endif
        
        return true
    endfunction
    
    
    private function Init takes nothing returns nothing
        set pGetModuleHandle = (GameDLL + 0x86D1D0) / 4
        set pGetProcAddress = (GameDLL + 0x86D280) / 4
        set pExportFromMpq = GameDLL + 0x737F00
    endfunction
    
endlibrary
» RenderEdgeAPI
library RenderEdge initializer Init uses FpCall, Utils

    globals
        constant string RENDEREDGE_DLL = "RenderEdge_mini.dll"
        
        integer address_GetWindowX = 0
        integer address_GetWindowY = 0
        integer address_GetWindowWidth = 0
        integer address_GetWindowHeight = 0
        integer address_GetMouseX = 0
        integer address_GetMouseY = 0
    endglobals

    
    function GetWindowX takes nothing returns integer
        if (address_GetWindowX == 0) then
            set address_GetWindowX = GetModuleProcAddress(RENDEREDGE_DLL, "GetWindowX")
            return std_call1(address_GetWindowX, 0)
        else
            return std_call1(address_GetWindowX, 0)
        endif
        return -1
    endfunction
    
    function GetWindowY takes nothing returns integer
        if (address_GetWindowY == 0) then
            set address_GetWindowY = GetModuleProcAddress(RENDEREDGE_DLL, "GetWindowY")
            return std_call1(address_GetWindowY, 0)
        else
            return std_call1(address_GetWindowY, 0)
        endif
        return -1
    endfunction
    
    function GetWindowWidth takes nothing returns integer
        if (address_GetWindowWidth == 0) then
            set address_GetWindowWidth = GetModuleProcAddress(RENDEREDGE_DLL, "GetWindowWidth")
            return std_call1(address_GetWindowWidth, 0)
        else
            return std_call1(address_GetWindowWidth, 0)
        endif
        return -1
    endfunction
    
    function GetWindowHeight takes nothing returns integer
        if (address_GetWindowHeight == 0) then
            set address_GetWindowHeight = GetModuleProcAddress(RENDEREDGE_DLL, "GetWindowHeight")
            return std_call1(address_GetWindowHeight, 0)
        else
            return std_call1(address_GetWindowHeight, 0)
        endif
        return -1
    endfunction
    
    function GetMouseX takes nothing returns integer
        if (address_GetMouseX == 0) then
            set address_GetMouseX = GetModuleProcAddress(RENDEREDGE_DLL, "GetMouseX")
            return std_call1(address_GetMouseX, 0)
        else
            return std_call1(address_GetMouseX, 0)
        endif
        return -1
    endfunction
    
    function GetMouseY takes nothing returns integer
        if (address_GetMouseY == 0) then
            set address_GetMouseY = GetModuleProcAddress(RENDEREDGE_DLL, "GetMouseY")
            return std_call1(address_GetMouseY, 0)
        else
            return std_call1(address_GetMouseY, 0)
        endif
        return -1
    endfunction
    
    
    private function Init takes nothing returns nothing
        if (not ExportDllFromMpqAndInjectToWarcraft(RENDEREDGE_DLL, RENDEREDGE_DLL)) then
            call Message("Failed to inject " + RENDEREDGE_DLL)
        endif
    endfunction

endlibrary
» Demo
library Demo initializer Init uses InjectDLL, Interface, RenderEdge, Utils

    globals
        
    endglobals
    
    
    function GetAspectRatio takes nothing returns real
        return I2R(GetWindowWidth()) / I2R(GetWindowHeight())
    endfunction
    
    function GetWidescreenMul takes nothing returns real
        return (I2R(GetWindowWidth()) * 3.0) / (I2R(GetWindowHeight()) * 4.0)
    endfunction

    
    private function Init takes nothing returns nothing
        call SetBlackBorders(0.0, 0.0)
        call SetPortrait(0.04, 0.1, 0.08, 0.08 * GetWidescreenMul())
        call SetMinimap(0.66, 0.06, 0.12, 0.12 * GetWidescreenMul())
        
        call Message("Window Width:   " + I2S(GetWindowWidth()))
        call Message("Window Height:  " + I2S(GetWindowHeight()))
    endfunction

endlibrary

Благодарности



Просмотров: 863

» Лучшие комментарии


FTFire #1 - 1 неделю назад 0
Ребята вы мои спасители.Огромное спасибо.
quq_CCCP #2 - 1 неделю назад 0
Довольно интересно, осталось запилить норм дабл клик абилок =)
FTFire #3 - 1 неделю назад 0
При попытке сохранить получаю мгновенный вылет.Если нажать кнопку тестировать карту работает.Тестировалось на обычном редакторе и JNGP.
ENAleksey #4 - 1 неделю назад (отредактировано ) 0
FTFire, для компиляции кода нужно использовать экспериментальную версию PJass: Скачать
FTFire #5 - 1 неделю назад 0
ENAleksey, Как он примерно работает?
Sergarr #6 - 1 неделю назад 0
FTFire:
ENAleksey, Как он примерно работает?
Магия мемхака. Если точнее, то с помощью одного бага редактируется исполняемый игрой код, что позволяет делать с ней все что угодно, если ты настоящий программист.
NanO #7 - 1 неделю назад (отредактировано ) 0
deleted
С pJass разобрался.
Получаю 11 ошибок.
При попытке запуска фатал еррор.
Разобрался х2.
FTFire #8 - 1 неделю назад 0
Вылетает.
NanO, Как ты исправил вылет?
NanO #9 - 1 неделю назад 0
FTFire:
Вылетает.
NanO, Как ты исправил вылет?
AdicParser + AdicOptimizer отруби.
FTFire #10 - 1 неделю назад 0
Аж слезы потекли.
NanO, Хорошо теперь другой вопрос как перенести в свою карту?У меня в старой остались гуи функции.Сохраняется нормально но не запускается.
ENAleksey #11 - 1 неделю назад (отредактировано ) 1
Редактирование миникарты:
function SetMinimap takes real x, real y, real size returns nothing
    local integer pMinimapFrame = ReadGameUIArray(240) + 180
    local integer pParentFrame = ReadGameUIArray(263) + 180

    call SetFramePoint(pMinimapFrame, FRAME_BOTTOMLEFT, pParentFrame, FRAME_BOTTOMLEFT, x, 0.6 - y - size)
    call SetFramePoint(pMinimapFrame, FRAME_TOPRIGHT, pParentFrame, FRAME_BOTTOMLEFT, x + size, 0.6 - y)
endfunction
Карту обновлю позже, после того, как добавлю демонстрацию внедрения сторонних динамических библиотек.
прикреплены файлы
FTFire #12 - 1 неделю назад 0
ENAleksey, Я помню ты говорил что можно полностью скрыть интерфейс,при этом все кнопки и тд. будут работать.Это можно сделать в MemoryHack если да,есть код который скрывает это?
ENAleksey #13 - 1 неделю назад (отредактировано ) 0
FTFire, кода нет, как я уже писал, нужно искать первый аргумент функции SetFramePoint либо в IDA Pro, либо методом перебора значений в функции ReadGameUIArray.
FTFire #14 - 1 неделю назад 0
ENAleksey, Ясно нужно будет попробовать.
ENAleksey #15 - 1 неделю назад (отредактировано ) 6

Обновление v1.0.1a

  • Добавлено внедрение динамической библиотеки RenderEdge_mini.dll (извлекается из карты в папку с варкрафтом);
  • Widescreen Fix;
  • Добавлена функция для редактирования миникарты.
Функции из RenderEdge_mini.dll:
function GetWindowX takes nothing returns integer
function GetWindowY takes nothing returns integer
function GetWindowWidth takes nothing returns integer
function GetWindowHeight takes nothing returns integer
function GetMouseX takes nothing returns integer
function GetMouseY takes nothing returns integer
А вот некоторые фреймы, которые я нашёл:
ReadGameUIArray(239) + 180 // Black Borders
ReadGameUIArray(240) + 180 // Minimap
ReadGameUIArray(241)       // Unit InfoPanel
ReadGameUIArray(243)       // ResourceBarFrame
ReadGameUIArray(244)       // UpperButtonBarFrame
ReadGameUIArray(247)       // ?
ReadGameUIArray(248)       // IdlePeon
ReadGameUIArray(253) + 180 // Portrait
ReadGameUIArray(255) + 180 // ?
ReadGameUIArray(251)       // WorldFrameChatMessage

ReadGameUIArray(258)       // Minimap button 1
ReadGameUIArray(259)       // Minimap button 2
ReadGameUIArray(260)       // Minimap button 3
ReadGameUIArray(261)       // Minimap button 4
ReadGameUIArray(262)       // Minimap button 5
прикреплены файлы
ADOLF #16 - 1 неделю назад 3
Я правильно понял, вы опять пишите и читаете код процесса из игры?)
Парни, я когда то 100 лет назад (на самом деле лет 5) описывал уязвимость, которая позволяла из jass кода писать в память процесса, из-за чего вышел патч, который убрал return bug как таковой. Там все было просто - с помощью return bug можно было с ним работать как с int и задать любое другое смещение, не кратное 4. Потом подбирались специальные инструкции псевдокода jass, которые как-то устанавливали метки массивов, и позволяли писать в память процесса.
Я еще тогда написал маленькую утилу, которая патчила game.dll, а именно то место, где jass интерпритатор обрабатывал тип code - с помощью сплайсинга и одной логической операции просто устанавливал в 0 последние биты аддресса, в результате чего варианты типа code + 2 не прокатывали. Жалко, что до Близов мы тогда это так и не донесли ;)
Тут я, просмотрев код мельком вижу изменение фактического значение переменной типа code за счет какой-то работы с пространством имен локальных и глобальных переменных, нет?
Kind Ram #17 - 1 неделю назад 0
А как у вас получается собственные типы объявлять? У меня WE от этого начинает жаловаться, что не удалось инициализировать глобальные переменные.
quq_CCCP #18 - 1 неделю назад 0
ADOLF, xgm.guru/p/wc3/memoryhack
Kind Ram, а где тут собственные типы переменных?
16GB #19 - 1 неделю назад 0
Так а дополнительный интерфейс уже научились создавать? Например сделать закупку итемов как в доте, чисто на мемхаке?
quq_CCCP #20 - 1 неделю назад 0
16GB, Щя погодь, не то запилят...
Kind Ram #21 - 1 неделю назад 0
Прошу прощения перепутал, там обращение к библиотеке идёт)
Daniil18 #22 - 1 неделю назад 0
function GetMouseX takes nothing returns integer
function GetMouseY takes nothing returns integer
это для чего? отлавливает положение курсора? Просто уже чет такое выкладывали, но там время синхронизации довольно большое и неиграбельно в мультиплеере.
quq_CCCP #23 - 1 неделю назад 0
Daniil18, ну это тот же самый код, его рили выкладывали и давно... А вот для быстрого синха потребуется скорее всего собственная библиотека, будет ли она или нет хз, но судя по тому что народ начел проявлять нарастающий интерес к мемхаку то будет.
ADOLF #24 - 6 дней назад (отредактировано ) 1
Топик прочитал, описание уязвимости не нашел. Прочитал код еще раз, теперь днем - я правильно понял, махинации со значением переменной типа code осуществляются за счет некорректной проверки типов переменных jass интерпритатором самой игры, когда изначальное объявление глобальной переменной одного типа и потом объявление локальной переменной с тем же именем другого типа в одной функции заставляет интерпритатор ошибочно считать глобальную переменную переменной другого типа?
По итогу это тот же самый return bug, реализованный просто по другому. И, таким методом возможно же сделать идентичные старому rb функции в новых патчах, которые были выпущены после уязвимости 2012 года.
И что, Blizzard на это совсем забили, не пытаются лавочку прикрыть?
Я вот не помню, фиксированная ли длина у псевдокода, в который интерпритируется jass скрипт, но есть у меня подозрение, что если бы близы место убивания return bug в 2012 сделали так, как писал я - а именно выравнивание кода в функции, которая обрабатывает тип code - сейчас вызов по типу I2C(+2+C2I(c)) был бы невозможен, как и использование данной уязвимости.
Clamp #25 - 6 дней назад 2
И что, Blizzard на это совсем забили, не пытаются лавочку прикрыть?
С 1.28 можно только читать память, но запись прикрыли, причём как раз тем методом, что ты указал в статье на Хабре.
quq_CCCP #26 - 6 дней назад 2
Они та и не прикрыли сломанный массив и запись байткодов в массив для их выполнения...
ADOLF #27 - 6 дней назад 0
С 1.28 можно только читать память, но запись прикрыли, причём как раз тем методом, что ты указал в статье на Хабре.
Они та и не прикрыли сломанный массив и запись байткодов в массив для их выполнения...
Да, то, о чем писал я полностью бы закрыло возможно вообще работать с памятью из jass кода, они же, как кажется мне просто или вынесли jass в отдельную песочницу, или другим методом запретили интерпритатору писать куда не надо (насчет метода не уверен, давно не работал с архитектурой винды).
quq_CCCP #28 - 6 дней назад 0
ADOLF, лич писал что они стали применять антиотладочные технологии в новых патчах, и вроде прикрыли записиь каким то костылем.
ADOLF #29 - 6 дней назад 1
Интересно) Мы еще в 2012 пришли к выводу, что они уже абсолютно не понимают, как работает jass в игре из 2002 (а может и тех людей, которые это писали уже нет в команде), и не могут сделать нормальный патч. Логично, что в 2017 они тем более это не понимают ;)
quq_CCCP #30 - 6 дней назад 0
ADOLF, разработчик который знал про это дело, пропал в 2006, они рили непонимают ничего. Да иим не интересно это дело, на хайве они как то задавали вопрос что бы пользователи хотели увидеть в редакторе - у них глаза выпали от хотелок. Щя они уже взялись за баланс, обновлений двиги походу небудет......
Clamp #31 - 6 дней назад 2
ADOLF, по этой ссылке пост с описанием того, как была закрыта уязвимость.

а может и тех людей, которые это писали уже нет в команде
Так и есть.
quq_CCCP #32 - 6 дней назад 0
Clamp, там на второй странице он же и пишет, что тупые близзарды так и не пофиксили, просто сделали по своему...
Щяс уже собственно пофиг, 1.27 скорее всего последний патч, на котором будут сидеть, ибо постоянные глюки и несовместимости 100500 карт с новыми патчами, просто потому что там криворучки игру делают. Так что можно уже не беспокоится, мемхак есть и он работает и будет работать, пока близзарды не смогут предложить что либо в замен. Китайцы на 1.24 в большинстве сидят, делают патчи (на базе лаунчеров) сами, и офф батл нет им ненадобен.
Clamp #33 - 6 дней назад 0
он же и пишет, что тупые близзарды так и не пофиксили, просто сделали по своему...
Тащемта он пишет, что они пофиксили как он и указал, закрыв запись и оставив чтение.
Alexey98 #34 - 3 дня назад 0
это было в этой проге сделано? xgm.guru/p/100/195453
quq_CCCP #35 - 3 дня назад 0
Alexey98, Это не прога а библиотека, а то что вы скинули похоже на фотошоп.
Ну описание характеристик думаю слепить совсем изи, а то что на скрине хер сделаешь, уж очень много чего придется изменить...