-
Active Member
How am I off by this much - 1.15.x Obj Mgr
I have got an object manager working, but I don't understand why I am off by 0xB2.
Posts here helped find the function that seems to count objects and output some debug. I tried to rename all of the variables to sane objects but I havent finished yet. (Partial func below)
So my code searches for a sig of this function and reads these bytes
Code:
4c 8b 3d 9d 43 bf 01 // mov r15,QWORD PTR [rip+0x1bf439d]
I take the last 4 and read them as an int
Code:
0x1bf439d == 29311901
but when I add them to the rip (where i read the bytes from ending in 44) I get a value that is 0xB2 lower than what the disassembler is pointing too
So in my code I add this value it all works and I can iterate, I just dont understand how i got it wrong
Insight would be really helpful I expect its obvious
The decompiled func I am looking at
Code:
undefined8 UndefinedFunction_141d63430(void)
{
longlong *plVar1;
longlong *last_obj_ptr;
longlong *plVar3;
ulonglong uVar4;
uint *puVar5;
longlong lVar6;
undefined8 uVar7;
uint uVar8;
uint *puVar9;
uint *puVar10;
longlong lVar11;
uint uVar12;
int iVar13;
longlong *current_obj_ptr;
int count_units;
undefined8 *puVar16;
int count_objects;
int count_all_objects;
longlong unaff_GS_OFFSET;
int iStackX_18;
int copy_count_all_objects;
int stack_count_units;
int stack_count_objects;
int count_visible_objects;
lVar11 = obj_mgr_start_ptr;
count_all_objects = 0;
count_visible_objects = 0;
copy_count_all_objects = 0;
iStackX_18 = 0;
current_obj_ptr = *(longlong **)(obj_mgr_start_ptr + 0x48);
stack_count_units = 0;
stack_count_objects = 0;
// Waiting for loading / being ingame? (best guess)
plVar1 = current_obj_ptr + *(longlong *)(obj_mgr_start_ptr + 0x40) * 3;
if (((*current_obj_ptr == 0) && (current_obj_ptr[1] == 0)) ||
((*(longlong *)(obj_mgr_start_ptr + 0x58) != 0 &&
((*current_obj_ptr == 1 && (current_obj_ptr[1] == 0x400000000000000)))))) {
while (current_obj_ptr = current_obj_ptr + 3, current_obj_ptr < plVar1) {
if (((*current_obj_ptr != 0) || (current_obj_ptr[1] != 0)) &&
((*(longlong *)(obj_mgr_start_ptr + 0x58) == 0 ||
((*current_obj_ptr != 1 || (current_obj_ptr[1] != 0x400000000000000)))))) break;
}
}
last_obj_ptr = (longlong *)
(*(longlong *)(obj_mgr_start_ptr + 0x48) + *(longlong *)(obj_mgr_start_ptr + 0x40) * 0x18);
count_units = 0;
count_objects = 0;
iVar13 = 0;
if (current_obj_ptr != last_obj_ptr) {
puVar16 = (undefined8 *)(*plVar3 + 0x6490);
while (current_obj_ptr != last_obj_ptr){
uVar4 = current_obj_ptr[2];
puVar9 = (uint *)*puVar16;
uVar8 = (uint)(uVar4 >> 0x20);
uVar12 = (uint)uVar4;
// Check if object is visible?
if (((puVar9 != (uint *)0x0) && (*puVar9 == uVar8 >> 0x16)) ||
(puVar9 = (uint *)func_0x000140529f20(uVar4 >> 0x36), puVar9 != (uint *)0x0)) {
puVar5 = *(uint **)(*(longlong *)(puVar9 + 2) + (ulonglong)(uVar12 & 0x3fffffff) * 8);
puVar10 = (uint *)0x0;
if (uVar4 == *(ulonglong *)(puVar5 + 2)) {
puVar10 = puVar5;
}
if ((puVar10 != (uint *)0x0) &&
(*(char *)(*(longlong *)((ulonglong)*puVar10 * 0xc0 + 8 + *(longlong *)(puVar9 + 0x1a)) +
0x13) != -1)) {
count_visible_objects = count_visible_objects + 1;
}
}
// unsure
puVar9 = (uint *)*puVar16;
if (((puVar9 != (uint *)0x0) && (*puVar9 == uVar8 >> 0x16)) ||
(puVar9 = (uint *)func_0x000140529f20(uVar4 >> 0x36), puVar9 != (uint *)0x0)) {
puVar5 = *(uint **)(*(longlong *)(puVar9 + 2) + (ulonglong)(uVar12 & 0x3fffffff) * 8);
puVar10 = (uint *)0x0;
if (uVar4 == *(ulonglong *)(puVar5 + 2)) {
puVar10 = puVar5;
}
if ((puVar10 != (uint *)0x0) &&
(*(char *)(*(longlong *)((ulonglong)*puVar10 * 0xc0 + 8 + *(longlong *)(puVar9 + 0x1a)) +
0x12) != -1)) {
count_all_objects = count_all_objects + 1;
copy_count_all_objects = count_all_objects;
}
}
puVar9 = (uint *)*puVar16;
if (((puVar9 == (uint *)0x0) || (*puVar9 != uVar8 >> 0x16)) &&
(puVar9 = (uint *)func_0x000140529f20(uVar4 >> 0x36), puVar9 == (uint *)0x0)) {
LAB_141d63693:
// Identify and count units
puVar9 = *(uint **)(lVar6 + 0x6490);
count_all_objects = copy_count_all_objects;
if (((puVar9 != (uint *)0x0) && (*puVar9 == uVar8 >> 0x16)) ||
(puVar9 = (uint *)func_0x000140529f20(uVar4 >> 0x36), puVar9 != (uint *)0x0)) {
puVar5 = *(uint **)(*(longlong *)(puVar9 + 2) + (ulonglong)(uVar12 & 0x3fffffff) * 8);
puVar10 = (uint *)0x0;
if (uVar4 == *(ulonglong *)(puVar5 + 2)) {
puVar10 = puVar5;
}
if ((puVar10 != (uint *)0x0) &&
(*(char *)(*(longlong *)((ulonglong)*puVar10 * 0xc0 + 8 + *(longlong *)(puVar9 + 0x1a))
+ 5) != -1)) { // +5 for units
stack_count_units = stack_count_units + 1;
goto joined_r0x000141d63797; // jump to find next object
}
}
Last edited by boipus; 12-31-2024 at 07:27 AM.
-
Active Member
Relative addressing in intel assembly is relative to the start of the next instruction (not the current one). This doesn't account for a difference of 0xb2, but I figured i'd mention it anyways.
I'm using this code to compute relative addresses.
Code:
#define SCAN_OFFSET(p, s, pat) do { \
if (scan_offset(pat, sizeof(pat)-1, s, &(p)) == -1) { \
L("no %s", #p ); \
exit(99); \
} \
L("%s %p", #p , p); \
} while(0)
int
scan_offset(const char *pattern, int len, int offstart, void *out)
{
unsigned char *ptr;
uint64_t **out_val = out;
for (ptr = WOWSTART; ptr <= (WOWSTART + text_length - len); ptr++) {
if (is_match(ptr, pattern, len) == 0) {
int *offset = (int *)(ptr + offstart);
char *nexti = ptr + offstart + 4;
*out_val = (uint64_t *)(nexti + *offset);
return 0;
}
}
return -1;
}
for example, to find lua tainted. The off set to lua_tainted is 10 bytes into this machine sig.
Code:
/* lua_pushlstring
14164B880 48 8B 5F ?? mov rbx, [rdi+18h]
14164B884 4C 8B C6 mov r8, rsi
14164B887 48 8B 05 ?? ?? ?? ?? mov rax, cs:lua_tainted
14164B88E 48 8B D5 mov rdx, rbp
14164B891 48 8B CF mov rcx, rdi
14164B894 48 89 43 ?? mov [rbx+10h], rax
48 8B 5F ? 4C 8B C6 48 8B 05 ? ? ? ? 48 8B D5 48 8B CF 48 89 43 ?
^
*/
SCAN_OFFSET(lua_tainted, 10, "\x48\x8B\x5F\xff\x4C\x8B\xC6\x48\x8B\x05\xff\xff\xff\xff\x48\x8B\xD5\x48\x8B\xCF\x48\x89\x43\xff");
lua_taintexpected = (uint32_t*)(lua_tainted + 1);
L("lua_taintexpected: %p", lua_taintexpected);
-
Post Thanks / Like - 1 Thanks
boipus (1 members gave Thanks to thateuler for this useful post)