Jump to content

Edw590

Members
  • Posts

    3
  • Joined

  • Last visited

About Edw590

  • Rank
    New Member
    New Member

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Edw590

    EXE hacking

    So, in case it's useful to know here, this really seems to be possible! (In case this wasn't already known? At least in this thread I didn't see that, but no idea about other places - I don't follow Doom things, because I never played, at least yet.) Finished testing now. The patch patches itself to have the correct addresses, and then patches the EXE (calls, jumps, other values, anything) and when you call the patch's functions from the EXE, you don't need to pass any parameters! The contents of the BIN file remain in memory so that the EXE can jump or call or read its contents wherever it wants. It can jump or call to the EXE functions, and if inside the BIN file those functions need references to the EXE, they have them all already and there's no need to pass parameters. Just do the patch normally without thinking in passing parameters specifically for segment addresses and other stuff (not even my idea of function parameter to know which one to execute --> the EXE just calls the functions on the BIN file, because the patch patches the EXE's jumps and calls to go to the BIN file functions). One can also have global variables/strings and use the data segment and whatever segment is needed and the code will run just fine. I haven't made any patches to the EXE yet, but I've been testing from the call to the patch from the loader. The test function I'm using is a naked function and I pass no parameters to it at all. I managed to call printf from it to print a string in the EXE's data segment ("FALLOUT %p.%p") with the code and data segment addresses as parameters, print a "Hi!" string in the data segment of the BIN file, print a global int value in the BIN file's data segment (with "%d", also on the BIN file's data segment), then increment it and print it again, and call exit(), and all worked perfectly!!! (Being printf() and exit() functions from inside the EXE.) I can also call the EXE's functions from C. I made C functions with the same signature as the original standard ones with an Assembly implementation and I opened a file, read its contents to a local C variable and closed the file. In this case I can even put the patches to be choosable inside an INI file and let people edit the file easily to choose which patches they want applied! So I think this can be used exactly like DLL injection! You load it, let it be loaded, access stuff from inside its memory space, call its functions with references to the EXE's functions, whatever else you want. Not sure if this has any use here though, but at least for a beginner on these things seems to be wow ahahah. I'll still have to check the loader on the repo though. But I'll leave that to later as I'm having too much fun/excitement finding out these things right now ahah. PS: this doesn't mess on how the BIN file is loaded to memory. It just needs to pass 3 addresses in 3 registers or pass one of them and store the others in the block and the rest it's however the loader is implemented. I haven't touched the loader since I began trying these things. It's still loading as I left it 2 days ago or something. Update: just wanted to add a week later that it's no longer PoC. I'm patching a game function call to an external function. That function uses data and other functions from the game EXE. It also uses 2 external strings. I pass no parameters to it and I use only EDI to calculate all relocations, and I push and pop it every time (or if EDI is already in use, then ESI - 2 registers not much used and that are not used in Watcom's calling convention, and btw, EDI seems to be the less used one of the 2). All works perfectly! More ahead I'll have an external function calling another external function. And that will also work. If it's useful, I'm publising the code here: https://github.com/Edw590/F1DP. Thank you again xttl for all your published knowledge!!! EDIT: I made improvements to the explanation (no idea how many, it was months ago) in the GitHub link I've put above.
  2. Edw590

    EXE hacking

    Ah then it's no longer needed. No problem, at least shared the idea xD. With a quick overview, the idea of the hack seems to be so that it's not needed to patch the EXE? Or the main idea is another one? If it's to remove patching (and since I cannot use that exploit because it's for Doom(?)), then is there any difference between your original approach and the one you just described? (Because I still have to permanently patch and have wrappers) If it's not really about this, never mind. I'll have to properly read the loader code some time and understand what's happening there decently. Will have a look for sure though! Will save the link along with the patches on my PC. Thank you! AT&T syntax is kind of awful for me, but if it's needed, required and mandatory 😂, what can I do ahahah. Fallout seems to have everything passed on registers, except when there's a string involved (then its address gets pushed into the stack). So might mean hard way ahah. [I don't follow Doom things at all (never even played any Doom ahah), so I didn't know about that or anything else anyway. Some day I'll play a game to see what that's all about, but for now I haven't done it yet.] PS: about what you said of using wrappers to every function call. (Why do you say that btw? Sorry, I didn't get it. If it's just a call, why have a wrapper, and btw doing what inside?) The EDIT 5 of my previous message (about which I've been thinking all day ahahah) seem to have a way of me not having to need any wrapper, or actually even needing to store anything in the code segment at all. The loader calls the BIN file on a place of the main external function. That function reads the block itself and patches all absolute references according to the given code and data section addresses. After that, it actually patches the EXE with the values that were just patched on it --> the patch patches itself before it can patch the EXE ahahah. Not sure if this works, but in my head it seems to. This way I wouldn't need to store the block address (I won't need it anymore), or the code and data section addresses. Only if I want to free() the block in the exit (will have to see how bad it is if I don't free it... On Windows would be fine, on DOS might not be, but still, one just would have to restart the VM after exiting the game and that's it, I guess). EDIT: FYI, I just found out GCC can understand Intel x86 syntax if you give this compiling flag: -masm=intel (https://stackoverflow.com/questions/199966). EDIT 2: IT WORKS!!!!!! The patch is patching itself!!! I've managed to call a function that calls printf() and exit() from inside the external code without giving that function ANYthing at all!!!!! No need for any wrappers it seems!!! Just made my life easier xD aside from having learned a bit more!!! (Unless there are alternatives? So far this is the only way I've seen without needing wrappers for every patch function call. At least without some exploit or something(?)). EDIT 3: also, if what I just thought works, one can have global variables and strings placed in whatever segment!!! No more local variables-only thing nor creating strings on the stack with manual assignment with chars by index (awful ahahah) nor code-segment-only programming or whatever limitations!!!! Just make a normal program with normal flags and all shouod work! Will test this tomorrow...
  3. Edw590

    EXE hacking

    @xttl Hi. I just created an account here to say thank you. For a beginner on reverse engineering like me, seems this thread should probably be archived ahah (I'll do it on my own way at least). So THANK YOU!!! I'm messing with Fallout 1 DOS EXE (which is also a Linear Executable LE EXE) and this was exactly what I needed to know!!! I can now patch functions in run-time because of this idea of giving the function the addresses of the segments!!! I had just found out what relocations were and then I understood the reason why it was working on the PC and not on the tablet (didn't seem to make much logic until I learned this). I was thinking in making some automated tool to add things to the relocation table, but then I found this piece of gold. So, thank you again. About this, I just wanted to give you (and/or to anyone else) an idea, which I don't know if you already thought of or not (in case you're still at this though - I read the entire thread, so no idea if you're still on this or not). The idea is very simple actually, and seems to have worked here. As a start I'm doing something which came to my mind (and that I believe you mentioned around the thread, no idea where? Or I'm confusing with something else), which is to write on the code section the 3 addresses: the allocated block address, the code section address, and the data section address. Then, every time before you call the functions in the external file, before calling the function you want, push the ESI and EDI, call the next instruction, you just need to do: call $+5 pop esi mov esi, [esi+offset from the previous instruction to where the Code section address is] mov edi, [esi+IDA offset to where the Data section address is] call [esi+IDA offset to where the allocated block address is] Or if you want to go to somewhere specific, put add edx, [whatever] after the last mov. This way I was able to patch a string address from the allocated block code! First time I patched stuff in run-time ahah. [Btw, I'm thinking in just appending to the end of the EXE, which if I remember correctly, won't do anything bad because the header says the last page ends at a specific place and then everything else is just ignored(?). And this way I don't need to have another file around. I know where the the last page ends, so I can put everything else on the allocated block.] Note: I'm storing the addresses in the code section because I don't know which parts of the data section are not used. And there are about 3k null bytes in the last code section page, so I extended the section and started writing there. I also still need to set the section as writable. I haven't done it and it still works (like it did with you as you wrote somewhere here). Not sure why though (the loaders don't like to read!?), but ok. Thank you again! You just spared me a LOT of work moving the EXE contents down to add bytes to the tables and other awful stuff (and gave me some more ideas to the pack in case I ever need again ahah). Seems "DLL injection" works here xD (kind of). Never messed with that (yet, at least), but I think that's how it works, if I'm not mistaken. EDIT: I think one can even do something like this. This way you just need to CALL codecave or JMP to it (where you choose which function to execute on the external file or do other things, for example), and then only use JMPs here on the code above so when you RETurn from the external file (if it was a CALL), you go directly to where you were when you called codecave. Or you can just JMP to the codecave and keep the stack anyway (and then just use a JMP to where you want, though it must be with an absolute address with the Code section address help). Just don't forget of POPing EAX inside the function you called so the stack (and the register) can get back to normal. No idea if this is still useful for here xD, but in case it is, it's here. EDIT 2: actually one can just store the address of the allocated block address and keep the Code section and Data section addresses in the beginning of the block too. If I'm not missing anything, that would save using either ESI or EDI. Only one would be needed (to store the block address). You'd have more instructions to go on memory get the addresses though, but one more register would be available. I've edited the code to have this idea in mind. When you leave the external file, you need to reset the ESI register through the allocated block. This way the stack remains intact (less bugs and less hating life? xD). EDIT 3: to answer another thing, you can have the loader wherever you want, not just on some specific place. You just need to have it in a fixed place (as it should anyway), and then subtract the IDA address from the address after the call instruction. I'm doing that right now. I call the loader from more or less the beginning of main() with a call, and inside I figure out where I am (same idea as I said above, just applied to the loader). EDIT 5: I think one could even get the patcher to patch itself xD. Would make the code above and the need to call that function every time a hack is needed, not needed at all. When the patcher is first called, it patches itself, so next times when it gets called from the functions, it already has the correct addresses on it. I'll try to go this route (seems simpler).
×
×
  • Create New...