Skip to content

Instantly share code, notes, and snippets.

@FransBouma
Last active June 16, 2019 14:37
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FransBouma/6b41665b14d006be32d081ff69ded3a4 to your computer and use it in GitHub Desktop.
Save FransBouma/6b41665b14d006be32d081ff69ded3a4 to your computer and use it in GitHub Desktop.
Hitman 2016 Final CT camera table, with smooth movement. For v1.7. By Jim2Point0 and myself.
<?xml version="1.0" encoding="utf-8"?>
<CheatTable CheatEngineTableVersion="21">
<CheatEntries>
<CheatEntry>
<ID>11022</ID>
<Description>"Camera system. Toggle: INS. Enable first"</Description>
<LastState/>
<VariableType>Auto Assembler Script</VariableType>
<AssemblerScript>//----------------------------------------------------------
// Reworked Hitman 2016 cheat table with free camera / timestop / FoV
// Original camera / timestop: Jim2Point0
// Reworked camera / threading code: Otis / Infuse Project
//
// For Hitman v1.7.0.
//
// this table contains a thread based camera movement system which moves the camera based on the camera look vector direction
// so pressing e.g. 'left' (numpad 4) is moving the camera left, you're no longer moving over the world x/y/z axis which don't align with
// the camera direction in most cases.
//
// I've commented a lot of code in this table. For seasoned assembly programmers these comments might sound like 'water is wet' statements,
// but they might help the novice assembly programmer out what's going on (as SIMD programmer isn't straightforward!) :)
// The features are enabled / disabled by two child scripts, one for the FoV and one for the camera hook.
// This is done so the thread loop can run at almost full speed scanning keys and it's also easier to enable e.g. FoV without the
// camera.
//----------------------------------------------------------
[ENABLE]
globalalloc(OwnCode, 2048) // alloc memory for our code, once.
createthread(MainThread)
//----------------------------------------------------------
// Code labels
label(MainThread)
label(MainThread_EndLoop)
label(GrabCameraStructAddress)
// Data labels
label(_disableThread)
label(_cameraStruct)
label(_cameraEnabled)
label(_fovEnabled)
label(_altPressed)
label(_ctrlPressed)
label(_lockCamera)
label(MoveCameraSidewaysRight)
label(PerformLockCamera)
// Symbols. Registering them allows you to use them in the CE UI.
registersymbol(_disableThread)
registersymbol(_cameraStruct)
registersymbol(_cameraEnabled)
registersymbol(_fovEnabled)
registersymbol(_lockCamera)
registersymbol(MainThread)
registersymbol(MainThread_EndLoop)
registersymbol(GrabCameraStructAddress)
registersymbol(MoveCameraSidewaysRight)
registersymbol(PerformLockCamera)
OwnCode:
// Grab camera structure address, which is inside the camera struct we need.
// There are more instructions here, as the overwrite is bigger (14 bytes), as it uses a
// qword address sourced jump instead of a simple jump because the jump is into global allocated memory!
GrabCameraStructAddress:
cmp [rbx+38],0 // could also check +20 or +24 for 0 if the above fails
jne GrabCameraOriginalCode
mov [_cameraStruct], rbx
cmp byte [_cameraEnabled], 1
je ExitCameraStructGrab // camera enabled, skip original code.
GrabCameraOriginalCode:
movss [rbx+00000090],xmm0 // original statement
movss xmm0,[rsp+58] // original statement
ExitCameraStructGrab:
jmp ReturnAfterCameraStructGrab
// The lock mouse code.
// There are more instructions here, as the overwrite is bigger (14 bytes), as it uses a
// qword address sourced jump instead of a simple jump because the jump is into global allocated memory!
PerformLockCamera:
movaps xmm0,[rax] // original statement
cmp byte [_lockCamera], 1
je @f
movups [rbx+00000080],xmm0 // original statement, performs write.
@@:
movss xmm0,[rsp+50] // original statement
jmp ReturnAfterPerformLockCamera
//---------------------------------------------------------
// Code
MainThread:
// x64 calls to Win32 functions uses Windows ABI 64 bit calling convention: create 'shadow space on the stack
// for the first 4 arguments and 16-byte align the stack, which happens to be 40 bytes. Result is stored in RAX.
// So that's the sub rsp/add rsp statements doing around Win32 calls.
sub rsp, 28
mov rcx, #25
call kernel32.Sleep // for some reason CE compiles 'Sleep' wrong, but does do it properly when kernel32.Sleep is used. Oh well...
add rsp, 28
// check if the thread can die
cmp [_disableThread], 1
je MainThread_End // disabled, die
// check if the camera struct is already available. If not, loop to the beginning of the thread,
// which will be a sleep call. We do this as the thread can be created before the hook is set in the process.
cmp qword ptr [_cameraStruct], 0
je MainThread
// check if one of the keys is pressed
// keys supported:
// Camera pos: num8 (forward), num4 (backward), num6 (right), num4 (left), num9 (up), num3 (down).
// Enable/disable depends on separate script (see table)
// FoV : substract (decrease FoV), add (increase FoV). Enable/disable depends on separate script (see table)
// We'll do this one at a time, as it doesn't matter if we e.g. check up+left or first up and then left
// Camera position manipulation keys are ignored if camera is disabled
// We'll check with GetKeyState, and not GetAsyncKeyState, as GetAsyncKeyState can fail if CE is on a different monitor
// than the game.
//
// FoV keys
@@:
sub rsp, 28
mov rcx, 6D // numpad substract (VK_SUBSTRACT)
call GetKeyState
add rsp, 28
test ax, 8000
jz @f
// key pressed, do fov decrease
call DoFoVDecrease
@@:
sub rsp, 28
mov rcx, 6B // numpad add (VK_ADD)
call GetKeyState
add rsp, 28
test ax, 8000
jz @f
// key pressed, do fov inccrease
call DoFoVIncrease
@@:
sub rsp, 28
mov rcx, 6A // numpad mul (VK_MULTIPLY)
call GetKeyState
add rsp, 28
test ax, 8000
jz @f
// key pressed, reset fov
mov rcx, [_cameraStruct]
mov [rcx+17c], (float)0.7
@@:
// Free camera movement keys
// first check if the free camera is enabled. Enabling is done by a different script.
cmp byte [_cameraEnabled], 1
jne MainThread_EndLoop
// camera enabled, we can proceed with handling camera movement keys
// Check if alt is pressed. If so, we'll speed up the movement. We'll store the bit for later
mov rcx, 12 // Alt (VK_MENU)
call GetKeyState
and eax, 8000 // high bit is either set (key is pressed) or not (key isn't pressed). Rest of bits is garbage, so clear them
shr ax, F // so we simply shift right 15 bits, which moves the high bit to the LSB
mov [_altPressed], ax
// Check if ctrl is pressed. If so, we'll slow down the movement. Same code as Alt. We'll store the bit for later
mov rcx, 11 // Ctrl (VK_CONTROL)
call GetKeyState
and eax, 8000
shr ax, F
mov [_ctrlPressed], ax
mov rcx, 68 // numpad 8 (VK_NUMPAD8)
call GetKeyState
test ax, 8000
jz @f
// up is pressed, perform camera move forward.
call MoveCameraForward
@@:
mov rcx, 62 // numpad 2 (VK_NUMPAD2)
call GetKeyState
test ax, 8000
jz @f
// down is pressed, perform camera move backwards
call MoveCameraBackwards
@@:
mov rcx, 64 // numpad 4 (VK_NUMPAD4)
call GetKeyState
test ax, 8000
jz @f
// left is pressed, perform camera move sideways
call MoveCameraSidewaysLeft
@@:
mov rcx, 66 // numpad 6 (VK_NUMPAD6)
call GetKeyState
test ax, 8000
jz @f
// right is pressed, perform camera move sideways
call MoveCameraSidewaysRight
@@:
mov rcx, 69 // numpad 9 (VK_NUMPAD9)
call GetKeyState
test ax, 8000
jz @f
// z up is pressed, perform camera move upwards along Z axis
xor rbx, rbx // if rbx is set to 0 for this function it will move up, otherwise down
call MoveCameraUpDown
@@:
mov rcx, 63 // numpad 3 (VK_NUMPAD3)
call GetKeyState
test ax, 8000
jz @f
// z down is pressed, perform camera move downwards along Z axis
mov rbx, 1
call MoveCameraUpDown
@@:
MainThread_EndLoop:
// check if the thread can die
cmp [_disableThread], 1
jne MainThread // not disabled, so loop!
MainThread_End:
// end
mov [_disableThread], 2
ret
//-------------------------------------------------------------
// camera movement code
// We're using a normalized (vector with length 1.0) vector to move the camera.
// this vector is at [_cameraStruct]+60, with vX, vY, vZ, W. This is the 3rd row in the camera matrix in general, and also in this case.
// The 'W' isn't used, but as the SIMD instructions load 128bits into the registers, they'll load the 4th dword too.
//
// The vector is the camera look vector so we can use that to manipulate the camera coordinates:
// Forward means we're moving in the direction of the vector (X, Y and Z updated)
// Left/Right means we're moving in the x/y plane in the direction orthogonal on the look vector (X, Y updated, Z is left alone)
// Backwards means we're moving in the opposite direction of the vector (X, Y and Z updated)
// The vector uses (-x, -y, z) compared to the world/geometry coordinates. This means that
// if the vector is aligned with the x axis looking at the positive x of the world, it's vX component is negative. Same for vY.
// If you think 'Why is this bozo doing a sub when he wants to add?!', that's why ;)
MoveCameraForward:
push rax
mov rax, [_cameraStruct]
add rax, 90 // load camera X, Y, Z, W into xmm0. X is at [_cameraStruct+90]
movups xmm0, [rax]
sub rax, 30 // normalized vector is at [_cameraStruct+60]: vX, vY, vZ, vW
movups xmm1, [rax] // load normalized vector into xmm1 (vX, vY, vZ, vW)
call SizeLookVector // will apply alt/ctrl to vector in xmm1 so it makes movement either faster or slower.
subps xmm0, xmm1 // sub the vector from the camera pos, as we're moving in the direction of the vector, but the vector uses -x, -y. If it would have used x, y, we should have used addps
mov rax, [_cameraStruct]
add rax, 90
movups [rax], xmm0 // move the newly calculated pos back into the camera values.
pop rax
ret
MoveCameraBackwards:
push rax
mov rax, [_cameraStruct]
add rax, 90 // load camera X, Y, Z, W into xmm0. X is at [_cameraStruct+90]
movups xmm0, [rax]
sub rax, 30 // normalized vector is at [_cameraStruct+60]: vX, vY, vZ, vW
movups xmm1, [rax] // load normalized vector into xmm1 (vX, vY, vZ, vW)
call SizeLookVector // will apply alt/ctrl to vector in xmm1 so it makes movement either faster or slower.
addps xmm0, xmm1 // add the vector from the camera pos, as we're moving in the opposite direction of the vector, but the vector uses -x, -y. If it would have used x, y, we should have used subps
mov rax, [_cameraStruct]
add rax, 90
movups [rax], xmm0 // move the newly calculated position back into the camera position values.
pop rax
ret
//------------------------------------------------------------
// move left &amp; right will use the x/y portion of the normalized vector and set z to 0. This gives a vector in the x/y plane
// which potentially isn't of length 1 so we have to normalize it again.
// To refresh your memory concerning xmm regs: [0|1|2|3] are the parts. so vX is placed in the lower element (0), vY in (1) etc.
// I use it this way as CE displays xmm registers in that order in the debugger.
// so shuffle commands have their bits backwards compared to the order of the xmm elements: 33 22 11 00
// Clear? thought so :)
MoveCameraSidewaysLeft:
push rax
call GetCameraVectorAsXYVector // will load camera vector into xmm1, move it to x/y plane, normalize it
// move left means we have to rotate the x/y vector 90 degrees counter-clockwize. This is simple: new vector is (-vY, vX).
// first move the elements to the right position
shufps xmm1, xmm1, F1 // shuffle using: 11 11 00 01. xmm1 now contains (vY, vX, 0, vW)
xorps xmm2, xmm2 // set the value of xmm2 to 0
subss xmm2, xmm1 // substract 1st value of xmm1, which is vY, from 0
movss xmm1, xmm2 // move -vY from xmm2's first element into xmm1. xmm1 now contains (-vY, vX, 0, vW)
call SizeLookVector
mov rax, [_cameraStruct]
add rax, 90 // load camera X, Y, Z, W into xmm0. X is at [_cameraStruct+90]
movups xmm0, [rax]
subps xmm0, xmm1 // add the vector we calculated to the camera position. But x/y are negative aligned, remember? So we do sub! It should now move left
mov rax, [_cameraStruct]
add rax, 90
movups [rax], xmm0 // move the newly calculated position back into the camera position values.
pop rax
ret
MoveCameraSidewaysRight:
push rax
call GetCameraVectorAsXYVector // will load camera vector into xmm1, move it to x/y plane, normalize it
// move right means we have to rotate the x/y vector 90 degrees clockwize. This is simple: new vector is (vY, -vX).
xorps xmm2, xmm2 // set the value of xmm2 to 0
subss xmm2, xmm1 // substract 1st value of xmm1, which is vX, from 0
movss xmm1, xmm2 // move -vX from xmm2's first element into xmm1. xmm1 now contains (-vX, vY, 0, vW)
shufps xmm1, xmm1, F1 // shuffle using: 11 11 00 01. xmm1 now contains (vY, -vX, 0, vW)
call SizeLookVector
mov rax, [_cameraStruct]
add rax, 90 // load camera X, Y, Z, W into xmm0. X is at [_cameraStruct+90]
movups xmm0, [rax]
subps xmm0, xmm1 // add the vector we calculated to the camera position. But x/y are negative aligned, remember? So we do sub! It should now move right
mov rax, [_cameraStruct]
add rax, 90
movups [rax], xmm0 // move the newly calculated position back into the camera position values.
pop rax
ret
//------------------------------------------------------------
// Camera up / down movement is done by first creating a vector (0, 0, 1.0) as look vector, size it with the size code, and
// simply add it to the camera coords for up and sub it from the camera coords for down. Z is aligned with world coordinates Z.
// In: rbx: 0==up, not 0==down
MoveCameraUpDown:
push rax
call GetZVector // xmm1 now contains (0, 0, 1.0, 0)
call SizeLookVector // size it based on alt/ctrl keys
mov rax, [_cameraStruct]
add rax, 90 // load camera X, Y, Z, W into xmm0. X is at [_cameraStruct+90]
movups xmm0, [rax]
test rbx, rbx // check whether the register is set to 0. If so, we'll move up, otherwise we'll move down
je MoveCameraUpDown_Up
subps xmm0, xmm1 // sub the vector we calculated from the camera position. Z is aligned with the world axis, so we use sub
jmp MoveCameraUpDown_Store
MoveCameraUpDown_Up:
addps xmm0, xmm1 // add the vector we calculated to the camera position. Z is aligned with the world axis, so we use add (finally, some sanity!)
MoveCameraUpDown_Store:
mov rax, [_cameraStruct]
add rax, 90
movups [rax], xmm0 // move the newly calculated position back into the camera position values.
pop rax
ret
//------------------------------------------------------------
// returns in xmm1 a vector (0, 0, 1.0, 0).
// in: nothin'
// out: the vector (0, 0, 1.0, 0)
// Changes: xmm1
GetZVector:
push rax
xorps xmm1, xmm1 // set the value of xmm1 to 0
mov rax, (float)1.0
movd xmm1, rax // move 1.0 into xmm1. Which now contains 1.0, 0, 0, 0
shufps xmm1, xmm1, 45 // shuffle xmm1 so the 1.0 is placed at the 3rd element, which is Z. So we'll use: 01 00 01 01
pop rax
ret
// Loads the camera vector into xmm1, will reset vZ to 0 and will normalize the vector (vX, vY) to length 1.0.
// It's a bit dirty, as it will fail with the vector pointing along the Z axis and x/y being 0.0, but the game doesn't allow that
// In: nothin'
// Out: xmm1: normalized camera vector in x/y plane with vZ set to 0.0.
// Changes: xmm2, xmm3
GetCameraVectorAsXYVector:
push rax
mov rax, [_cameraStruct]
add rax, 60 // normalized vector is at [_cameraStruct+60]: vX, vY, vZ, vW
movups xmm1, [rax] // load normalized vector into xmm1 (vX, vY, vZ, vW)
xorps xmm2, xmm2 // reset xmm2 to 0, all 4 components
mov rax, -1
movd xmm2, rax // the 1st element (index 0) contains -1 (ffffffff).
shufps xmm2, xmm2, 10 // shuffle using: 00 01 00 00 all 4 elements are now filled with -1 except the 3rd (which contains Z)
andps xmm1, xmm2 // this will set the 3rd element (vZ) to 0, keep all other elements. xmm1 now contains (vX, vY, 0, vW)
// we now have to normalize the vector in xmm1, as it's not really a length of 1, as x/y are smaller if z isn't 0. This is
// done with the formula: vX=vX/length, vY=vY/length. Length = sqrt(x*x+y*y). So first we'll calculate the length.
// this is simple, we multiply xmm1 with itself. Of course in another register as we need xmm1 later.
movaps xmm2, xmm1 // xmm2 now contains xmm1's values
mulps xmm2, xmm2 // multiply xmm2 with itself, which means vX=vX*vX, vY=vY*vY, 0*0, vW=vW*vW (but we don't care about that)
movaps xmm3, xmm2 // move the values of xmm2 in xmm3 so we can move vY*vY to the slot 0 to add it to vX*vX
shufps xmm3, xmm3, F1 // shuffle using 11 11 00 01 so end result is vY*vY, vX*vX, 0, vW*vW
addss xmm2, xmm3 // adds the slot 0 values of xmm3 and xmm2 which means xmm2 now contains vX*vX + vY*vY.
sqrtss xmm2, xmm2 // square root the slot 0 value, so it now contains sqrt(vX*vX + vY*vY).
shufps xmm2, xmm2, 0 // shuffle the sqrt result to all slots0, 1 and 2 so we can div x and y (and z, but will result in 0) in one go.
// so use 00 00 00 00 to avoid div by 0 in the next statement.
divps xmm1, xmm2 // div xmm1 with xmm2, which means vX/sqrt(vX*vX+vY*vY), vY/sqrt(vX*vX+vY*vY), 0, vW
pop rax
ret
//------------------------------------------------------------
// Will multiply the camera vector with a scalar to size it up (if alt is pressed) or down (if ctrl is pressed)
// If no alt/ctrl is pressed, we size it with the scalar 2.0 to make moving around more pleasant
// in : xmm1 (vX, vY, vZ, vW)
// changes: xmm7
SizeLookVector:
push rbx
cmp byte [_altPressed], 1
jne @f
// alt pressed. Multiply with 2.0
mov rbx, (float)1.0
jmp SizeLookVector_Calc
@@:
cmp byte [_ctrlPressed], 1
jne @f
// ctrl pressed. Multiply with 0.05
mov rbx, (float)0.01
jmp SizeLookVector_Calc
@@:
// default scalar sizing
mov rbx, (float)0.1
SizeLookVector_Calc:
movd xmm7, rbx // load the factor to multiply with into xmm7. This is a scalar, xmm registers contain 4 of them
shufps xmm7, xmm7, 0 // so we shuffle the first element to be placed in all 4.
mulps xmm1, xmm7 // multiply the vector in xmm1 with the 4 values in xmm7, so vX=vX*xmm7[0], vY=vY*xmm7[1] etc.
SizeLookVector_End:
pop rbx
ret
//------------------------------------------------------------
// FoV code
DoFoVIncrease:
cmp byte [_fovEnabled], 1
je @f
// not enabled, nothing to do.
ret
@@:
push rax
push rbx
mov rax, [_cameraStruct]
add rax, 17c // FoV value is at offset 17c. Contains 0.7 for normal fov.
movss xmm0, [rax]
mov rbx, (float)0.01 // load the register with 0.01 float, and move it using this register into xmm1
movd xmm1, rbx
addss xmm0, xmm1 // add the 0.01 to the value.
movss [rax], xmm0 // store the new value back into the address.
pop rbx
pop rax
ret
DoFoVDecrease:
cmp byte [_fovEnabled], 1
je @f
// not enabled, nothing to do.
ret
@@:
push rax
push rbx
mov rax, [_cameraStruct]
add rax, 17c // FoV value is at offset 17C
movss xmm0, [rax]
mov rbx, (float)0.01 // load the register with 0.01 float, and move it using this register into xmm1
movd xmm1, rbx
subss xmm0, xmm1 // sub the 0.01 from the value
movss [rax], xmm0 // store the new value back into the address.
pop rbx
pop rax
ret
//-----------------------------------------------------------
// Local data
_cameraStruct:
dq 0
_disableThread:
dd 0
_cameraEnabled:
db 0
_fovEnabled:
db 0
_lockCamera:
db 0
_altPressed:
dw 0
_ctrlPressed:
dw 0
// overwrite inside the Hitman process the following address with a jmp to our code which grabs the camera struct address
// which is in the register rbx.
// Remember this is compiled to a long jmp so will take up 14 bytes!
//"hitman.exe"+419037A:
"hitman.exe"+41C5B9A:
jmp GrabCameraStructAddress
ReturnAfterCameraStructGrab:
// Lock camera overwrite. Remember this is compiled to a long jmp so will take up 14 bytes!
//"hitman.exe"+419036A:
"hitman.exe"+41C5B8A:
jmp PerformLockCamera
nop
nop
ReturnAfterPerformLockCamera:
[DISABLE]
_cameraStruct:
dq 0
_disableThread:
dd 1
_cameraEnabled:
db 0
_fovEnabled:
db 0
_lockMatrix:
db 0
_altPressed:
dw 0
_ctrlPressed:
dw 0
// ALWAYS replace overwritten memory of all subnodes here, as the user can leave them ON and disable this one
// which will result in a crash if we don't overwrite them back to normal.
// Camera
//"hitman.exe"+419037A:
"hitman.exe"+41C5B9A:
movss [rbx+00000090],xmm0
movss xmm0,[rsp+58]
//"hitman.exe"+4190388:
"hitman.exe"+41C5BA8:
movss [rbx+00000098],xmm0
//"hitman.exe"+4190390:
"hitman.exe"+41C5BB0:
movss [rbx+00000094],xmm1
// Lock Camera:
//"hitman.exe"+419036A:
"hitman.exe"+41C5B8A:
movaps xmm0,[rax]
movups [rbx+00000080],xmm0
movss xmm0,[rsp+50]
// Fov
//"hitman.exe"+44E4887:
//je hitman.CAkRegisteredObj::~CAkRegisteredObj+425C6A
//movss xmm0,[hitman.Ordinal277+1303614]
"hitman.exe"+44E4887:
je hitman.exe+44E48B9
movss xmm0,[hitman.exe+1312714]
"hitman.exe"+44E48A9:
movss [rcx+0000017C],xmm0
// unregister symbols, as they're no longer needed
unregistersymbol(_disableThread)
unregistersymbol(_cameraStruct)
unregistersymbol(_cameraEnabled)
unregistersymbol(_fovEnabled)
unregistersymbol(_lockCamera)
unregistersymbol(MainThread)
unregistersymbol(MainThread_EndLoop)
unregistersymbol(GrabCameraStructAddress)
unregistersymbol(MoveCameraSidewaysRight)
unregistersymbol(PerformLockCamera)
</AssemblerScript>
<Hotkeys>
<Hotkey>
<Action>Toggle Activation</Action>
<Keys>
<Key>45</Key>
</Keys>
<ID>0</ID>
</Hotkey>
</Hotkeys>
<CheatEntries>
<CheatEntry>
<ID>11034</ID>
<Description>"Lock mouse. Toggle: F5"</Description>
<LastState/>
<VariableType>Auto Assembler Script</VariableType>
<AssemblerScript>[ENABLE]
_lockCamera:
db 1 // sets flag in main script's thread data
[DISABLE]
_lockCamera:
db 0 // resets flag in main script's thread data
</AssemblerScript>
<Hotkeys>
<Hotkey>
<Action>Toggle Activation</Action>
<Keys>
<Key>116</Key>
</Keys>
<ID>0</ID>
</Hotkey>
</Hotkeys>
</CheatEntry>
<CheatEntry>
<ID>11015</ID>
<Description>"FOV. Toggle: HOME"</Description>
<LastState/>
<VariableType>Auto Assembler Script</VariableType>
<AssemblerScript>[ENABLE]
_fovEnabled:
db 1 // sets flag in main script's thread data
"hitman.exe"+44E4887:
db 90 90
"hitman.exe"+44E48A9:
db 90 90 90 90 90 90 90 90
[DISABLE]
_fovEnabled:
db 0 // resets flag in main script's thread data
// original fov write code.
"hitman.exe"+44E4887:
je hitman.exe+44E48B9
movss xmm0,[hitman.exe+1312714]
"hitman.exe"+44E48A9:
movss [rcx+0000017C],xmm0
</AssemblerScript>
<Hotkeys>
<Hotkey>
<Action>Toggle Activation</Action>
<Keys>
<Key>36</Key>
</Keys>
<ID>0</ID>
</Hotkey>
</Hotkeys>
<CheatEntries>
<CheatEntry>
<ID>11020</ID>
<Description>"Num+/-: change FOV. Num*: reset"</Description>
<LastState Value="" RealAddress="00000000"/>
<Color>008000</Color>
<GroupHeader>1</GroupHeader>
</CheatEntry>
</CheatEntries>
</CheatEntry>
<CheatEntry>
<ID>11032</ID>
<Description>"Free camera. Toggle: END. Num2/8:Y, Num4/6:X, Num3/9:Z"</Description>
<LastState/>
<VariableType>Auto Assembler Script</VariableType>
<AssemblerScript>[ENABLE]
_cameraEnabled:
db 1 // sets flag in main script's thread data
//"hitman.exe"+4190390:
"hitman.exe"+41C5BA8:
db 90 90 90 90 90 90 90 90
//"hitman.exe"+4190388:
"hitman.exe"+41C5BB0:
db 90 90 90 90 90 90 90 90
[DISABLE]
_cameraEnabled:
db 0 // resets flag in main script's thread data
// original camera y/z write code. X write code is re-instated through the flag in the main script and when main
// script is disabled.
//"hitman.exe"+4190388:
"hitman.exe"+41C5BA8:
movss [rbx+00000098],xmm0
//"hitman.exe"+4190390:
"hitman.exe"+41C5BB0:
movss [rbx+00000094],xmm1
</AssemblerScript>
<Hotkeys>
<Hotkey>
<Action>Toggle Activation</Action>
<Keys>
<Key>35</Key>
</Keys>
<ID>0</ID>
</Hotkey>
</Hotkeys>
<CheatEntries>
<CheatEntry>
<ID>11033</ID>
<Description>"Alt: speed up. Ctrl: Slow down"</Description>
<LastState Value="" RealAddress="00000000"/>
<Color>008000</Color>
<GroupHeader>1</GroupHeader>
</CheatEntry>
</CheatEntries>
</CheatEntry>
</CheatEntries>
</CheatEntry>
<CheatEntry>
<ID>11006</ID>
<Description>"Game Speed [F3]"</Description>
<LastState/>
<Color>000000</Color>
<VariableType>Auto Assembler Script</VariableType>
<AssemblerScript>[ENABLE]
aobscanmodule(timeAOB,hitman.exe,F3 0F 59 43 48 F3 0F 59 05)
alloc(newmem,2048,"hitman.exe")
label(returnhere)
label(exit)
label(gameSpeed)
registersymbol(gameSpeed)
registersymbol(timeAOB)
newmem:
mov [gameSpeed],rbx
mulss xmm0,[rbx+48]
jmp exit
exit:
jmp returnhere
//
///
gameSpeed:
dq 0
///
timeAOB:
jmp newmem
returnhere:
[DISABLE]
dealloc(newmem)
timeAOB:
mulss xmm0,[rbx+48]
unregistersymbol(gameSpeed)
unregistersymbol(timeAOB)
</AssemblerScript>
<Hotkeys>
<Hotkey>
<Action>Activate</Action>
<Keys>
<Key>114</Key>
</Keys>
<ID>0</ID>
</Hotkey>
</Hotkeys>
<CheatEntries>
<CheatEntry>
<ID>10297</ID>
<Description>"Resume [F4]"</Description>
<LastState Value="" RealAddress="00000000"/>
<Color>8000FF</Color>
<GroupHeader>1</GroupHeader>
</CheatEntry>
<CheatEntry>
<ID>10296</ID>
<Description>"Pause [F3]"</Description>
<LastState Value="" RealAddress="00000000"/>
<Color>8000FF</Color>
<GroupHeader>1</GroupHeader>
</CheatEntry>
<CheatEntry>
<ID>11007</ID>
<Description>"Game Speed"</Description>
<VariableType>Float</VariableType>
<Address>gameSpeed</Address>
<Offsets>
<Offset>48</Offset>
</Offsets>
<Hotkeys>
<Hotkey>
<Action>Set Value</Action>
<Keys>
<Key>114</Key>
</Keys>
<Value>0.0001</Value>
<ID>0</ID>
<ActivateSound/>
<DeactivateSound/>
</Hotkey>
<Hotkey>
<Action>Set Value</Action>
<Keys>
<Key>115</Key>
</Keys>
<Value>1</Value>
<ID>1</ID>
<ActivateSound/>
<DeactivateSound/>
</Hotkey>
</Hotkeys>
</CheatEntry>
</CheatEntries>
</CheatEntry>
<CheatEntry>
<ID>11037</ID>
<Description>""</Description>
<LastState Value="" RealAddress="00000000"/>
<GroupHeader>1</GroupHeader>
</CheatEntry>
<CheatEntry>
<ID>11035</ID>
<Description>"By -= Jim2Point0 &amp; Otis / Infuse Project =-"</Description>
<LastState Value="" RealAddress="00000000"/>
<Color>FF8000</Color>
<GroupHeader>1</GroupHeader>
</CheatEntry>
<CheatEntry>
<ID>11036</ID>
<Description>"https://www.deadendthrills.com/forum/discussion/512/guide-hitman-2016"</Description>
<LastState Value="" RealAddress="00000000"/>
<Color>FF8000</Color>
<GroupHeader>1</GroupHeader>
</CheatEntry>
<CheatEntry>
<ID>11038</ID>
<Description>"For game version: 1.7.0"</Description>
<LastState Value="" RealAddress="00000000"/>
<Color>0000FF</Color>
<GroupHeader>1</GroupHeader>
</CheatEntry>
</CheatEntries>
<CheatCodes>
<CodeEntry>
<Description>Camera Z</Description>
<Address>144190388</Address>
<ModuleName>hitman.exe</ModuleName>
<ModuleNameOffset>4190388</ModuleNameOffset>
<Before>
<Byte>0F</Byte>
<Byte>10</Byte>
<Byte>44</Byte>
<Byte>24</Byte>
<Byte>58</Byte>
</Before>
<Actual>
<Byte>F3</Byte>
<Byte>0F</Byte>
<Byte>11</Byte>
<Byte>83</Byte>
<Byte>98</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
</Actual>
<After>
<Byte>F3</Byte>
<Byte>0F</Byte>
<Byte>11</Byte>
<Byte>8B</Byte>
<Byte>94</Byte>
</After>
</CodeEntry>
<CodeEntry>
<Description>Camera X</Description>
<Address>14419037A</Address>
<ModuleName>hitman.exe</ModuleName>
<ModuleNameOffset>419037A</ModuleNameOffset>
<Before>
<Byte>0F</Byte>
<Byte>10</Byte>
<Byte>44</Byte>
<Byte>24</Byte>
<Byte>50</Byte>
</Before>
<Actual>
<Byte>F3</Byte>
<Byte>0F</Byte>
<Byte>11</Byte>
<Byte>83</Byte>
<Byte>90</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
</Actual>
<After>
<Byte>F3</Byte>
<Byte>0F</Byte>
<Byte>10</Byte>
<Byte>44</Byte>
<Byte>24</Byte>
</After>
</CodeEntry>
<CodeEntry>
<Description>Camera Y</Description>
<Address>144190390</Address>
<ModuleName>hitman.exe</ModuleName>
<ModuleNameOffset>4190390</ModuleNameOffset>
<Before>
<Byte>83</Byte>
<Byte>98</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
</Before>
<Actual>
<Byte>F3</Byte>
<Byte>0F</Byte>
<Byte>11</Byte>
<Byte>8B</Byte>
<Byte>94</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
</Actual>
<After>
<Byte>EB</Byte>
<Byte>3B</Byte>
<Byte>48</Byte>
<Byte>8D</Byte>
<Byte>4C</Byte>
</After>
</CodeEntry>
<CodeEntry>
<Description>FOV 2</Description>
<Address>1444AEA69</Address>
<ModuleName>hitman.exe</ModuleName>
<ModuleNameOffset>44AEA69</ModuleNameOffset>
<Before>
<Byte>72</Byte>
<Byte>03</Byte>
<Byte>0F</Byte>
<Byte>28</Byte>
<Byte>C1</Byte>
</Before>
<Actual>
<Byte>F3</Byte>
<Byte>0F</Byte>
<Byte>11</Byte>
<Byte>81</Byte>
<Byte>7C</Byte>
<Byte>01</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
</Actual>
<After>
<Byte>E9</Byte>
<Byte>AA</Byte>
<Byte>A8</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
</After>
</CodeEntry>
<CodeEntry>
<Description>FOV 1</Description>
<Address>1444AEA47</Address>
<ModuleName>hitman.exe</ModuleName>
<ModuleNameOffset>44AEA47</ModuleNameOffset>
<Before>
<Byte>89</Byte>
<Byte>FC</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
</Before>
<Actual>
<Byte>74</Byte>
<Byte>31</Byte>
</Actual>
<After>
<Byte>F3</Byte>
<Byte>0F</Byte>
<Byte>10</Byte>
<Byte>05</Byte>
<Byte>C3</Byte>
</After>
</CodeEntry>
<CodeEntry>
<Description>Rotation Matrix?</Description>
<Address>14419036D</Address>
<ModuleName>hitman.exe</ModuleName>
<ModuleNameOffset>419036D</ModuleNameOffset>
<Before>
<Byte>24</Byte>
<Byte>54</Byte>
<Byte>0F</Byte>
<Byte>28</Byte>
<Byte>00</Byte>
</Before>
<Actual>
<Byte>0F</Byte>
<Byte>11</Byte>
<Byte>83</Byte>
<Byte>80</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
<Byte>00</Byte>
</Actual>
<After>
<Byte>F3</Byte>
<Byte>0F</Byte>
<Byte>10</Byte>
<Byte>44</Byte>
<Byte>24</Byte>
</After>
</CodeEntry>
</CheatCodes>
<UserdefinedSymbols>
<SymbolEntry>
<Name>pHealth</Name>
<Address>34760000</Address>
</SymbolEntry>
<SymbolEntry>
<Name>tHealth</Name>
<Address>34760010</Address>
</SymbolEntry>
<SymbolEntry>
<Name>pSkillPts</Name>
<Address>04E80020</Address>
</SymbolEntry>
<SymbolEntry>
<Name>AOB4_jmp</Name>
<Address>00723165</Address>
</SymbolEntry>
<SymbolEntry>
<Name>pWrath</Name>
<Address>04100020</Address>
</SymbolEntry>
<SymbolEntry>
<Name>pCurrency</Name>
<Address>05010000</Address>
</SymbolEntry>
<SymbolEntry>
<Name>AOB2_jmp</Name>
<Address>00726238</Address>
</SymbolEntry>
<SymbolEntry>
<Name>AOB5_jmp</Name>
<Address>00811E9C</Address>
</SymbolEntry>
<SymbolEntry>
<Name>AOB3_jmp</Name>
<Address>0078347E</Address>
</SymbolEntry>
<SymbolEntry>
<Name>AOB1_jmp</Name>
<Address>007248D2</Address>
</SymbolEntry>
<SymbolEntry>
<Name>AOB6_jmp</Name>
<Address>00761711</Address>
</SymbolEntry>
<SymbolEntry>
<Name>_fovAddress</Name>
<Address>345A00F1</Address>
</SymbolEntry>
<SymbolEntry>
<Name>_cameraX</Name>
<Address>32E50308</Address>
</SymbolEntry>
<SymbolEntry>
<Name>_cameraY</Name>
<Address>32E5030C</Address>
</SymbolEntry>
<SymbolEntry>
<Name>_cameraZ</Name>
<Address>32E50310</Address>
</SymbolEntry>
<SymbolEntry>
<Name>_altPressed</Name>
<Address>32E5031A</Address>
</SymbolEntry>
<SymbolEntry>
<Name>coords</Name>
<Address>13FFF00DA</Address>
</SymbolEntry>
<SymbolEntry>
<Name>coords2</Name>
<Address>0D3B0042</Address>
</SymbolEntry>
<SymbolEntry>
<Name>ammo</Name>
<Address>006F5C80</Address>
</SymbolEntry>
<SymbolEntry>
<Name>invis1</Name>
<Address>00A0A926</Address>
</SymbolEntry>
<SymbolEntry>
<Name>coords3</Name>
<Address>0D3F0029</Address>
</SymbolEntry>
<SymbolEntry>
<Name>OwnCode</Name>
<Address>369D0000</Address>
</SymbolEntry>
<SymbolEntry>
<Name>_fovAOB</Name>
<Address>1444AEA47</Address>
</SymbolEntry>
<SymbolEntry>
<Name>toggleLock</Name>
<Address>13FFD00E3</Address>
</SymbolEntry>
<SymbolEntry>
<Name>currentMode</Name>
<Address>13FFD00DF</Address>
</SymbolEntry>
</UserdefinedSymbols>
<Comments>Info about this table:
</Comments>
</CheatTable>
@FransBouma
Copy link
Author

v1.02: Fixed:

  • flying objects which shouldn't fly now don't fly anymore.
  • Moving sideways now doesn't affect Z anymore.

@FransBouma
Copy link
Author

Updated camera for v1.7.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment