I tried to change binary 6A 01 to 6A A2 which should change to 162 (turkish charset) but instead turned to negative value.
Usually the instruction set reference is a huge help if you don't understand how instructions behave. In this case, I'd say you will need to use 68
(PUSH imm32
) instead of 6A
(PUSH imm8
). The imm8
is sign-extended when pushed onto the stack. Note that you'll have to either shift the following function code by 3 bytes (which are the difference in sizes between imm32
and imm8
operands). Depending on the compiler used, its options, and the function size, there may be pad bytes after the function which can be used exactly for that. Watch out for e.g. jump tables, if there are any -- they may need to be patched as well.
If it is not possible to shift the code, you can make use of code space somewhere else in the executable -- usually, the last page in .text
is not fully used; move instructions that do not fit there and make a jump, like:
...
PUSH EDI
PUSH EDI
PUSH A2 ; Your patched insn; 5 bytes
...
PUSH 190
PUSH EDI
PUSH EDI
; So we need 2 extra bytes here
; Moving CALL gives 6, patched PUSH takes 3, patched JMP takes 5
; Moving two PUSHes along with CALL solves the problem
JMP _somewhere_ ; Takes 5 bytes, opcode E9 disp32
PUSH Game5_4.... ; back is here
And then, in the newly coded part (_somewhere_
):
PUSH EDI
PUSH EAX
CALL DWORD PTR DS:[<&GDI32.CreateFontA>]
JMP back
Is changing CP_ACP
to CP_UTF8
gonna work ?
I don't know, to be honest. Depends a lot on other code. Making the program support something it was not designed for is a big ordeal. It might work, it might not, it might end up being buggy.