Closed Cosetto closed 8 months ago
If you're implementing a custom UIF feature, you can use patch_memory
from utils.h
. That works essentially the same as your SysMemWrite
function. But UIF actually already comes with a built-in feature that can do this without any code modifications.
Apparently I forgot to write documentation for it in the readme, so here is how to use it.
Just add the following to your uif_config.json
:
{
"memory_patcher": {
"enable": true,
"patches": {
"myTargetModule.dll+0016BDB4h": "54 6F 61 6E 20 6D 61 6E 20 68 69 6E 68 20 28 4F 29 00",
"myTargetModule.dll+00172CB4h": "43 68 75 79 82 BA 6E 20 74 82 BC 6E 68 20 63 75 82 B1 69 0A 63 82 C1 6E 67 20 74 72 82 B5 6E 20 54 72 82 9F 69 20 83 83 82 A5 74 2E 00"
}
}
}
If your image_base
refers to the main executable, you can omit the myTargetModule.dll+
part of the addresses. Also note that the address offset must end in h
or H
to signal that it's a hexadecimal number, otherwise it's parsed as decimal. The patch bytes must be separated by a single space and if any of them are less than 16, they need a leading zero.
When working with text, make sure to include the null terminator in the patch bytes. And keep in mind that the patched text can't be longer than the original one, because then it might override other data.
Hm, I tried with utf8 hex, but it turned out like this.
Aside from that, what is the format we use to patch with string?
Well the new string has to use the same encoding as the original. The code processing these strings doesn't magically get changed to support UTF-8 if it expects to find Shift-JIS strings.
So the next step is to determine which API ultimately consumes the string. That would probably be InsertMenu
or a related function, since it ends up in a popup menu. The UIF text processing features (tunnel_decoder
and character_substitution
) currently don't support those menu APIs, but they should be fairly straightforward to add hooks for. Assuming the program uses codepage 932 / Shift-JIS, you can encode the string with arc's tunnel encoding. Then we'd just need to implement the appropriate hook for the tunnel decoder.
I was planning a rework of the entire text processing subsystem in the near-ish future, so I can look into adding support for the relevant APIs. I can't make any promises regarding times though, so if you want to add the hooks yourself, check out the existing hooks in tunnel_decoder.cpp
.
Aside from that, what is the format we use to patch with string?
I'm not entirely sure what you mean by that. Are you asking whether there is a way to specify the replacement string directly instead of converting it to a byte sequence manually? If so the answer is no, patch data currently has to be specified in the format described above. That may change in the future, but so far it wasn't necessary.
Ah, I see. Thank you for your answer. Guess I'll wait for that day to come.
@Cosetto could you share the executable so I can check which function needs to be hooked?
@AtomCrafty Here eden_en.zip
Which proxy dll are you using?
I'm using winmm
winmm.zip Please check whether this works.
Edit: I forgot to disable the old hook It seems like nothing changed
Could you copy/paste the console output for me to check?
DllMain: attach InstallDelayedAttachHook: start InstallDelayedAttachHook: no target module specified InstallDelayedAttachHook: transaction InstallDelayedAttachHook: end Attach: run Attach: unhook injector::attach: enabled DllMain: detach
Not the log file, the output shown in the console window that should open with the program. Should look something like this.
Universal Injector Framework, created by AtomCrafty, 2021 Loaded configuration: { "allocate_console": true, "text_processor": { "conversion_codepage": 65001, "enable": true, "enabled_apis": [ "AppendMenuA" ], "rules": [ { "apis": [ "AppendMenuA" ], "match": "Full screen (&O)", "replacement": "Toàn màn hình", "type": "replace_full_string" } ] } } [injector] ====================================================== [injector] Injecting into module eden_en.exe at address 00400000 [injector] Loading original library from C:\Windows\system32\winmm.dll [text_processor] Hooking import AppendMenuA in eden_en.exe at 005492E4 --> 6C831680 [injector] Initialization complete [injector] ======================================================
winmm.zip I added some debug output, maybe that will shed some light on what's going on here.
Btw if you use Discord, you can add me there (@atomcrafty). That might be easier for this kind of troubleshooting.
winmm.zip I think I found the issue. Try this one.
Oh nice, it works! Thank you so much!
Sweet!
So, is the correct way to continue?
Every rule definition needs to be in its own {}
block.
Thanks!
Weird, this time the "window_manager" didn't work
[window_manager] Warning: Unable to hook import DefWindowProcA because it has already been hooked by feature text_processor
The title uses Unicode, so I have to use the "text_processor" for it too?
text_processor
replaces all of the old text modification features, including window_manager
.
Use this configuration instead:
@AtomCrafty Any idea for Unicode string?
Add MessageBoxW
to the enabled_apis
list and use this rule:
{
"type": "replace_full_string",
"apis": ["MessageBoxW"],
"match": "Are you sure you want to exit?",
"replacement": "Translation here"
}
Lol, it seems like each Unicode string has bytes to indicate the length before it. So that was why it didn't catch full string.
How the data is represented in memory shouldn't matter at all, since UIF doesn't touch it there. This data is manipulated by the application and the end result is ultimately passed to one of the MessageBox__
functions. It only matters what is passed to that function since that is where UIF does the replacement. But looking at the executable it appears that it uses MessageBoxA
instead of MessageBoxW
, so try replacing both instances in your config.
Oh, it works now. Thanks again pal!
Sorry for bothering you again, but it looks like there are few more string which don't use MessageBoxA. Do you know how to determine which api they use?
The program probably never sets the text explicitly, but just tells Windows to create the dialog from that template. So there is no API UIF could intercept to change the string. Looks like you're already using Resource Hacker, so the easiest option would be to just edit the dialog template right there.
Aight'
Hi @AtomCrafty Could you add a function to support changing the font size?
@staciaa123 Please create a separate issue for your feature request.
Hello there, the Window Manager function works very great, but I wonder is it possible to add a function like it for text in exe? Like this link You have RVA (Relative Virtual Address), and you can change the text at that address.
But the problem is I want to use it in your proxies because it converts Ansi to UTF16 for special characters.