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
PUSH imm32) instead of
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
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 A2 ; Your patched insn; 5 bytes
; 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 (
CALL DWORD PTR DS:[<&GDI32.CreateFontA>]
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.