hwo to correctly assemble hexadecimal float?
wkingnet opened this issue · 2 comments
Hi, I'm here again. I'm continuing to hack my game, now I am studying how to control the game characters to walk. This part of the work requires the construction of several floating-point stack parameters.
Now i have a new problem. It seems that PythonForWindows cannot assemble float correctly.
this is my python code:
def call_template(self, ebx, arg1=None, arg2=None, arg3=None, arg4=None,
arg5=None, arg6=None, arg7=None, arg8=None, arg9=None):
code = x86.MultipleInstr()
code += x86.Pushad()
code += x86.Mov("EBP", "ESP")
if arg9 is not None:
code += x86.Push(arg9)
if arg8 is not None:
code += x86.Push(arg8)
if arg7 is not None:
code += x86.Push(arg7)
if arg7 is not None:
code += x86.Push(arg6)
if arg5 is not None:
code += x86.Push(arg5)
if arg4 is not None:
code += x86.Push(arg4)
if arg3 is not None:
code += x86.Push(arg3)
if arg2 is not None:
code += x86.Push(arg2)
if arg1 is not None:
code += x86.Push(arg1)
code += x86.Mov("ECX", address['call_ecx'])
code += x86.Mov("EBX", ebx)
code += x86.Call("EBX")
code += x86.Mov("esp", "ebp")
code += x86.Popad()
code += x86.Ret()
logger.info(f"""asm run""")
run_asm(code, pid=self.pid)
pos_cur_x = read_addr(address['player_pos_cur_x'], data_type='float')
pos_cur_y = read_addr(address['player_pos_cur_y'], data_type='float')
ebx = address['call_city_go']
arg1 = pos_dst_x
arg2 = read_addr(address['player_pos_cur_x'] + 4, data_type="float")
arg3 = pos_dst_y
arg4 = read_addr(address['player_pos_cur_y'] + 4, data_type="float")
arg5 = get_sin(pos_dst_x, pos_dst_y, pos_cur_x, pos_cur_y)
arg6 = 0
arg7 = get_cos(pos_dst_x, pos_dst_y, pos_cur_x, pos_cur_y)
arg8 = 0
arg9 = read_addr(address['status_base_turn'], data_type="float", offset_list=[0xF4])
print(ebx, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
call_template(ebx, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
In game, the assembly stack of the game itself is like this, float 32bit:
But if running the code through python, the stack parameter becomes unsigned short 16bit:
debug in pycharm, it is still float variable:
So, how can I correctly assemble floating-point numbers?
By the way, could you update the version on Pypi? It will be very convenient for users to update
Thanks.
After several hours of trying, I wrote a small piece of code to convert float to hex, which worked very well
def float2hex(_float):
import struct
result = ""
for i in struct.pack('f', _float):
i = hex(i)[2:]
if len(i) % 2 == 1:
i = "0" + i
result = result + i
result = "68" + result # 68 means "push" 0x????
return result
code += x86.Raw(float2hex(pos_dst_y - pos_cur_y))
Hello,
Thank you for the issue, and well done for the solution.
As none of simple_x86
and simple_x64
implement any float instruction, and as I am not that familiar with CPython float
representation nor IEEE Standard for Floating-Point Arithmetic (IEEE 754)
. I think that trying float interpretation here would break more thing than the potential benefit.
For your use-case what you should be able to do is something similar to your solution by using struct to reeinterpret a float as a int with :
def float_as_int(_float):
return struct.unpack("<I", struct.pack("f", _float))[0]
>>> windows.native_exec.simple_x86.Push(float_as_int(22271.2)).get_code()
b'hf\xfe\xadF'
Even here, I am not sur this is the exact result you are looking for.