Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Special Hex String Construct for Mobile Label Addresses #33

Closed
Tracked by #130
OrionSR opened this issue Jul 16, 2020 · 15 comments
Closed
Tracked by #130

Special Hex String Construct for Mobile Label Addresses #33

OrionSR opened this issue Jul 16, 2020 · 15 comments
Labels
Milestone

Comments

@OrionSR
Copy link

OrionSR commented Jul 16, 2020

The issue is that CleoA uses a label search strategy to find structure addresses so scripts are compatible with multiple versions of the game. The hex constructs used to store the label string won't decompile without IGNORE_UNKNOWN, and is returned as a hex bytes. which works, but provides little useful information on how to adapt the code.

These constructs are always used in combination with a label used by opcode 0DD0:. I'm wondering if that's enough information for Sanny to format the hex construct as a null terminated string. Or maybe there's a better solution, because this "Magic Hex" construct is extremely common in CleoA scripts - anything that accesses memory and isn't complete garbage.

Example (used in script body):

// Markuza97's any-version address codes - read once
0DD0: 6@ = get_label_addr @_ZN6CRadar13ms_RadarTraceE
0DD1: 6@ = get_func_addr_by_cstr_name 6@ // start of marker structure
0DD0: 7@ = get_label_addr @gMobileMenu   
0DD1: 7@ = get_func_addr_by_cstr_name 7@ // start of... menu data?
000A: 7@ += 0x48 // offset to marker index

Labels (traditionally appended to the end of the script):

// Markuza97's magic hex codes
:gMobileMenu
hex
"gMobileMenu" 00
end

:_ZN6CRadar13ms_RadarTraceE
hex
"_ZN6CRadar13ms_RadarTraceE" 00
end
@XMDS
Copy link
Member

XMDS commented Jul 21, 2020

In fact, SB will always turn the string contained in hex into hexadecimal after decompilation. This makes the code unreadable

@XMDS
Copy link
Member

XMDS commented Jul 21, 2020

On the PC version:

{$CLEO}

0AC6: 0@ = label @Kernel32_dll offset
0AC6: 1@ = label @ASM_call_GetModuleHandleExA offset
0AC6: 2@ = label @GetModuleHandleExA offset
end_thread 

:Kernel32_dll
hex
 "Kernel32.dll" 00
end

:GetModuleHandleExA
hex
 "GetModuleHandleExA" 00
 end

:ASM_call_GetModuleHandleExA
hex
{0000} 55              //push    ebp
{0001} 8BEC            //mov     ebp, esp
{0003} 83EC 04         //sub     esp, 4
{0006} 8D45FC          //lea     eax, [ebp-4]  
{0009} 50              //push    eax
{000A} 8B45 04         //mov     eax, [ebp+4] 
{000D} 50              //push    eax
{000E} 6A 06           //push    6
{0010} E8 00000000     //call    GetModuleHandleExA
{0015} 8B45FC          //mov     eax, [ebp-4]
{0018} 83C4 04         //add     esp, 4
{001B} 5D              //pop     ebp
{001C} C3              //ret
end

After decompilation:

{$CLEO .cs}

//-------------MAIN---------------
0AC6: 0@ = label @Noname_32 offset 
0AC6: 1@ = label @Noname_64 offset 
0AC6: 2@ = label @Noname_45 offset 
004E: end_thread 

:Noname_32
hex
 4B 65 72 6E 65 6C 33 32 2E 64 6C 6C 00 47 65 74
 4D 6F 64 75 6C 65 48 61 6E 64 6C 65 45 78 41 00
end

:Noname_64
8B55:   not 
83EC:   not 
04EC: 
hex
 8D 45 FC 50 8B 45 04 50 6A 06 E8 00 00 00 00 8B
 45 FC 83 C4 04 5D C3

The code becomes unreadable hexadecimal. Although you can open it with Notepad to see the character names. As OrionSR said.
I hope SB can decompile the correct string. As for the ASM assembly code in the example. . . . . . . . This is just my wishful thinking, haha, it would be nice if the compiled assembly code can also be decompiled. How about giving SB a function of automatic assembly and machine code conversion? Write the assembly directly when writing in this way, and automatically convert to machine code after compilation?

@XMDS
Copy link
Member

XMDS commented Jul 21, 2020

Even on Android CLEO:

{$CLEO}

:get_CPed
//0A96: 9@ = actor $PLAYER_ACTOR struct
0DD0: 9@ = get_label_addr @_ZN6CPools6GetPedEi
0DD1: 9@ = get_func_addr_by_cstr_name 9@
0DD3: context_set_reg 0 value $PLAYER_ACTOR
0DD2: context_call_func 9@
0DD4: 4@ = context_get_reg 0 //CPed
end_thread

:_ZN6CPools6GetPedEi
hex
 "_ZN6CPools6GetPedEi" 00
end

For example, the pointer structure of the player obtained above, after decompilation:

0DD0: 9@ = get_label_addr @Noname_39 // android 
0DD1: 9@ = get_func_addr_by_cstr_name 9@ // android 
0DD3: context_set_reg 0 value $PLAYER_ACTOR // android 
0DD2: context_call_func 9@ // android 
0DD4: 4@ = context_get_reg 0 // android 
004E: end_thread 

:Noname_39
hex
 5F 5A 4E 36 43 50 6F 6F 6C 73 36 47 65 74 50 65
 64 45
end
0069: // (float) 

They are very messy, this kind of bad code

@XMDS
Copy link
Member

XMDS commented Jul 21, 2020

When only using a function, put the function name at the end. Decompilation does not affect the sorting of the previous CLEO code.
But when you use multiple functions or allocate a piece of static memory space, the decompiled code will be worse:

https://github.com/XMDS/Cleo-source-code/blob/master/XMDS/Android/SA/Realtime.txt

Here I have a "real time CLEO" that I wrote before (the game time is synchronized with the phone system time). The decompilation is very bad... In fact, I really like the structure of Android CLEO, even though the SB tool is currently used for Android GTA scripts Compilation/decompilation is bad.

In fact, if the string {function name} cannot be decompiled correctly. So is it possible to add a function of importing strings to SB (only for Android GTA). To make it decompile correctly.

@x87
Copy link
Collaborator

x87 commented Jul 21, 2020

Thanks for all the examples. I don't think this can be solved in a general way, i.e. it would be impossible to cover all possible use cases with hex.end input. But particularly for 0DD0 I think we could make another debug flag that will allow to treat the content at the referenced label as a null-terminated character sequence.

@x87
Copy link
Collaborator

x87 commented Jul 21, 2020

@XMDS

How about giving SB a function of automatic assembly and machine code conversion? Write the assembly directly when writing in this way, and automatically convert to machine code after compilation?

I believe @Deji69 had this feature in his Scrambl compiler. We might discuss this in a separate ticket if you will.

@x87
Copy link
Collaborator

x87 commented Jul 21, 2020

They are very messy, this kind of bad code

there is "Add extra info" option in Sanny Builder to get better decompilation results with hex.end specifically. Does it help?

@XMDS
Copy link
Member

XMDS commented Jul 21, 2020

Finally, there is an Android CLEO issue.
I am trying to implement static injection of ARM assembly code in Android CLEO. I succeeded, but there is an architectural problem. I very much hope that the SB tool can add a function to solve the problem:

{$CLEO .csa}
0000:
jump @1

:ASM
hex
 AEF12D00 //SUB R0, LR, #0x2D
 F746     //MOV PC, LR
end

:1
wait 0
0DD0: 39@ = get_label_addr @ASM
0DD8: 1@ = read_mem_addr 39@ size 4 add_ib 0
39@ += 4
0DD8: 2@ = read_mem_addr 39@ size 2 add_ib 0
39@ -= 4
0DD9: write_mem_addr 39@ value 1@ size 4 add_ib 0 protect 1
39@ += 4
0DD9: write_mem_addr 39@ value 2@ size 2 add_ib 0 protect 1
39@ -= 4
//It must be read first, and then written as protect 1. 
//Because what Android CLEO.so is loaded is not the game memory space,
// but the static memory space allocated by the Android system, 
//which cannot be accessed directly. 
//This may be because of the rigor of the Android system

39@ += 1 
//Because it is a thumb instruction, the return address is automatically +1
//BLX will automatically recognize the switching instruction set
//The lowest bit of BLX address is 1 for Thumb, and 0 for Arm
//Android GTA uses ARMV7 and Thumb mixed instructions
0DD2: context_call_func 39@
0DD4: 0@ = context_get_reg 0 //0@= asm call addr
0DD8: 10@ = read_mem_addr 0@ size 1 add_ib 0
01E5: show_text_1number_highpriority GXT 'NUMBER' number 10@ time 10000 flag 1
end_thread

The above code gets the memory address of the function asm_call in CLEO.SO in the Android cleo library, and reads its first byte for display.
Just test the code, in fact, 0DD2 CALL calls itself to access its own address. This is also the OP implementation of ODD2.

But the problem is not here. The ASM assembly code at the beginning must be placed at the beginning of CLEO. If placed at the end, the game will crash and report an error.
After I spent time researching, the error code is as follows:

Exception signal: 7 (SIGBUS)
Exception code: Ox1 (BUS_ ADRALN)

When accessing memory, the data is not aligned
The new code is placed at the end:

0DD0: 39@ = get_label_addr @ASM
0DD8: 1@ = read_mem_addr 39@ size 4 add_ib 0
39@ += 4
0DD8: 2@ = read_mem_addr 39@ size 2 add_ib 0
39@ -= 4
0DD9: write_mem_addr 39@ value 1@ size 4 add_ib 0 protect 1
39@ += 4
0DD9: write_mem_addr 39@ value 2@ size 2 add_ib 0 protect 1
39@ -= 4
39@ += 1
0DD2: context_call_func 39@
0DD4: 0@ = context_get_reg 0
0DD8: 10@ = read_mem_addr 0@ size 1 add_ib 0
01E5: show_text_1number_highpriority GXT 'NUMBER' number 10@ time 10000 flag 1
end_thread

hex
00
end

If you do not add hex 00 end here to fill a byte to align the data, the game will crash. I noticed that this problem only occurs in Android, which is also the particularity of the architecture. It seems that the CLEO code will affect the alignment in memory?
It would be better if SB can automatically add extra bytes when compiling Android CLEO, but this is only suitable for advanced Android CLEO development

:ASM
hex
AEF12D00 //SUB R0, LR, #0x2D
F746     //MOV PC, LR
end

@XMDS
Copy link
Member

XMDS commented Jul 21, 2020

They are very messy, this kind of bad code

there is "Add extra info" option in Sanny Builder to get better decompilation results with hex.end specifically. Does it help?

Yes, the source code will be retained if you check to add additional information. This is indeed a good way. But not everyone does it

@x87 x87 mentioned this issue Jul 21, 2020
@x87
Copy link
Collaborator

x87 commented Jul 21, 2020

Finally, there is an Android CLEO issue.

let's continue in #36

@OrionSR
Copy link
Author

OrionSR commented Jul 21, 2020

I think disabling Extra Info was added to Mobile Coding 101 back when storage space on mobile devices was considerably more limited. I have seen very few examples of advanced mobile scripts that use this option.

Even on PC, Extra Info is usually only included with scripts from beginners that haven't explored SB's options yet, or scripts designed with the explicit intent of sharing the original code.

I suspect the basic player instinct is to disable Extra Info to hide your sloppy coding strategies, or to discourage people from stealing what you worked so hard to create.

@XMDS
Copy link
Member

XMDS commented Jul 21, 2020

I think disabling Extra Info was added to Mobile Coding 101 back when storage space on mobile devices was considerably more limited. I have seen very few examples of advanced mobile scripts that use this option.

Even on PC, Extra Info is usually only included with scripts from beginners that haven't explored SB's options yet, or scripts designed with the explicit intent of sharing the original code.

I suspect the basic player instinct is to disable Extra Info to hide your sloppy coding strategies, or to discourage people from stealing what you worked so hard to create.

Yes. Usually not checked. Because it affects the lock. There are also some encrypted CLEOs in the writing of Android CLEO. But there is nothing advanced. They use the compilation mechanism of the SB tool to hide their code. I have studied this encryption method. However, Android CLEO is largely limited, and I don't like the so-called deliberate concealment of code. For example, I provided the method for reading and writing the Android configuration ini file before, but others have encrypted their CLEO when they know it.

@OrionSR
Copy link
Author

OrionSR commented Jul 22, 2020

I guess another problem with the mobile hex strings is that it encourages players to think too much about locking strategies. I usually recommend tossing any script that is deliberately locked but for mobile scripts it's often hard to tell the difference. So for this particular case, I'm really hoping that a better strategy can be developed.

@x87 x87 added this to the CLEO Android Support milestone Aug 31, 2020
@x87 x87 added priority:p2 Medium priority and removed status:in dev triage labels Jul 24, 2021
@x87 x87 modified the milestones: CLEO Android Support, v3.8.0 Jul 24, 2021
@x87 x87 mentioned this issue Jul 24, 2021
48 tasks
@x87
Copy link
Collaborator

x87 commented Jul 25, 2021

@XMDS in v3.8.0-beta.1 disassembler should be able to write the content of a hex..end block as a string. Please try it and share your feedback with me.

@XMDS
Copy link
Member

XMDS commented Jul 27, 2021

@XMDS in v3.8.0-beta.1 disassembler should be able to write the content of a hex..end block as a string. Please try it and share your feedback with me

After a short period of testing, I have not found any problems for the time being. The string is currently decompiled correctly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants