opa334 / libundirect

Patchfinder and rebinder for objc_direct methods
MIT License
51 stars 8 forks source link

Unable to find offset in rootless, but able to in rootful #4

Open yur1xpp opened 8 months ago

yur1xpp commented 8 months ago

I'm using libundirect_find_with_options to find offset of a function, given the same unique bytes exist in both rootful and rootless binary (both are arm64), I should be able to find them correct? However, this is not the case. Code was not changed when compiled for iphoneos-arm64 and iphoneos-arm, except THEOS_PACKAGE_SCHEME=rootless is used for rootless.

It's working fine on Taurine, iPhone X, iOS 14.3 But not on Dopamine 2, iPhone 11 Pro Max, iOS 16.3.1

The binary I'm trying to find offset is actually Sileo, where I believe they are of the same in Taurine and Dopamine.

Do you have any insights what did I miss for rootless? Must be something that I missed since I'm not following the scene for quite some time.

opa334 commented 8 months ago

I don't see why it wouldn't work, I'm using it in e.g. Crane just fine.

I would generally recommend switching to ChOma for patchfinding, but you need to statically link that as there is no package available for it atm. Also, you will have to run ChOma on the file and then translate the file offset to the address in your process. I can't guarantee the ChOma API is stable atm though, so there might be changes in the future still. (This kind of thing is also why libundirect is unfixably broken, as I can't make changes to the old API).

yur1xpp commented 8 months ago

Been trying to find why libundirect failed for few days now, I gave up haha.

I'm trying to use choma at the moment, could you help me out on this? Since it's not very well documentated yet, I have hard time getting it to work.

FAT *fat = fat_init_from_path(ROOT_PATH("/Applications/Sileo.app/Sileo"));
if (fat){
    MachO *macho = fat_find_preferred_slice(fat);
    if (macho){
        PFSection *textSection = pfsec_init_from_macho(macho, "start", "__TEXT", "__text");
        # I think this line below is incorrect, Sileo kept crashing. 0x10010101010 is the function address where I found from disassembler. I feel like this is incorrect.
        if (pfsec_find_function_start(textSection, 0x10010101010)){
            // If I found the function start, how should I translate it?
            NSLog(@"FOUND");
        }
        macho_free(macho);
        pfsec_free(textSection)
    }
    fat_free(fat);
}
opa334 commented 8 months ago

it's macho, NULL, "__TEXT", "__text

Check out XPF for an example on how to do patchfinding, you will want a PFPatternMetric for the bytes you're checking. pfsec_find_function_start is only to find the start of a function from an offset into the middle of it.

yur1xpp commented 8 months ago

Okay I'm getting somewhere now. But how do you correctly translate the file offset? AFAIK this should do it right?

... start pfmetric_run block ...
uint64_t my_offset = pfsec_find_function_start(textSection, xrefaddr); # I verified that this is the address showing on my diassembler as well
MSHookFunction(((void *)((unsigned char *)_dyld_get_image_header(1) + my_offset), (void *)new, (void **)&old); # _dyld_get_image_header(1) is the Sileo image
... end pfmetric_run block ...

However, MSHookFunction didn't seems to be hooking anything. Does this has anything to do with ellekit? I didn't realize we have so few documentation floating around on the internet, especially on the modern tweak development (rootless). T.T

opa334 commented 8 months ago

Okay I'm getting somewhere now. But how do you correctly translate the file offset? AFAIK this should do it right?

... start pfmetric_run block ...
uint64_t my_offset = pfsec_find_function_start(textSection, xrefaddr); # I verified that this is the address showing on my diassembler as well
MSHookFunction(((void *)((unsigned char *)_dyld_get_image_header(1) + my_offset), (void *)new, (void **)&old); # _dyld_get_image_header(1) is the Sileo image
... end pfmetric_run block ...

However, MSHookFunction didn't seems to be hooking anything. Does this has anything to do with ellekit? I didn't realize we have so few documentation floating around on the internet, especially on the modern tweak development (rootless). T.T

First of all, do not rely on image 1 being the image you think it is. You need to enumerate the list of images and take the one that has the path you're looking for. Secondly, the offset you get is just that, an offset, it's not an address, try converting it (but I don't think this usually matters).

What I would suggest is, read some bytes at the offset and cofirm whether it's the place in memory you want it to be.