1

I'm trying to hack another program by changing the EIP of it. There are two programs running, one is the target, that tells where the function that is the "core-function"(e.g. a function that receive a password string as a parameter and returns true or false) is in memory. Then now that I know where the core-function is I wanna modify the EIP with the other program so the target program can call my function and simply get a true out of it and print out a beautiful "access granted".

My code is now like this:

Target Program:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


int checkPwd(char *pwd)
{
    printf("\nstill in the function\n");
    if(strcmp(pwd, "patrick") == 0) return true;
    else return false;
}


int main()
{
    char pwd[16];

    printf("%d", checkPwd);
    scanf("%s", &pwd);
    system("pause");
    if(checkPwd(pwd)) printf("Granted!\n");
    else printf("Not granted\n");
    system("pause");
}

Attacker Program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>

int returnTrue()
{
    return true;
}
int main()
{
    int hex;
    scanf("%d", &hex);
    memcpy((void*)hex, (void*)returnTrue, sizeof(char)*8);
    system("pause");
}

I wanna add that I tried to put the hex code directly(without the scanf part) in the attacker program and did not work, it crashed.

So I think I'm missing some part of the theory in here. I'd be glad to know what is it.

Thanks in advance.

AstroCB
  • 12,337
  • 20
  • 57
  • 73
Patrick Bassut
  • 3,310
  • 5
  • 31
  • 54
  • For something like this, you should probably include the assembly dump of the target program. – Mysticial Jul 13 '12 at 03:06
  • 1
    You overwrite EIP by messing with a return address on the stack. – user7116 Jul 13 '12 at 03:21
  • @sixlettervariables what you mean by that? – Patrick Bassut Jul 13 '12 at 03:25
  • Related http://stackoverflow.com/questions/5287874/buffer-overflow-attack-format and on [Windows you have other options](http://stackoverflow.com/questions/7575796/hooking-winapi-functions-called-from-dll) – user7116 Jul 13 '12 at 03:31
  • I'm on windows, but I don't wanna use WinAPI and make me dependent on this. And still don't get what you're trying to tell me about messing the stack. Could YOU be more clear? – Patrick Bassut Jul 13 '12 at 04:16
  • If you're on Windows, you won't get very much done at all if you try to avoid using the Windows API. You will need to use functions such as [`VirtualProtectEx`](http://msdn.microsoft.com/en-us/library/windows/desktop/aa366899(v=vs.85).aspx) and [`WriteProcessMemory`](http://msdn.microsoft.com/en-us/library/windows/desktop/ms681674(v=vs.85).aspx). – Greg Hewgill Jul 13 '12 at 05:08
  • You're saying that there's no way around, or things would be simpler? – Patrick Bassut Jul 13 '12 at 05:44
  • I just noticed that: I put "changing the EIP as title" but in code i'm actually trying to change the flow of it, right? Should I create another question for this? – Patrick Bassut Jul 13 '12 at 06:26
  • Actually, I put in "changing the EIP" as title—[you put in "How much does this take in memory?"](http://stackoverflow.com/posts/11463586/revisions) If you want to revise this question to something conceptually related, you could just edit this one. If it really is entirely different and what's been said here doesn't apply at all, then make a new one. – Asherah Jul 13 '12 at 06:33
  • I guess I did it wrong then. Cause my main goal is to change the flow of the program by patching the memory and adding some code so the other program could execute it. Is that the same thing? Sorry about that. – Patrick Bassut Jul 13 '12 at 06:45

2 Answers2

5

This won't work—the processes occupy different memory spaces!

Modern operating systems are designed to protect user programs from exactly this kind of attack. One process doesn't have access to the memory of another—and indeed, the addresses of data are only valid inside that process.

When a program is running, it has its own view of memory, and only can "see" memory that the kernel has instructed the memory management unit (MMU) to map for it.

Some references:

Community
  • 1
  • 1
Asherah
  • 18,948
  • 5
  • 53
  • 72
  • What about the programs that search values in memory and change it? What the SO does about that? Cause it works perfectly. – Patrick Bassut Jul 13 '12 at 03:24
  • @PatrickBassut: would you like to be a little more clear about what you mean? What you're trying to do is impossible for a regular user program to do, but I'm sure hacks involving the kernel (and therefore usually some sort of admin privilege) could do it for, e.g. trainers for games. – Asherah Jul 13 '12 at 03:59
  • I meant what I said. What part you want me to be clear about? But okay, now you mentioned that it's impossible for a "regular user program" to do. But still possible by hacking the kernel. So, the programs I'm talking about do hack the kernel? Alright. – Patrick Bassut Jul 13 '12 at 04:02
  • 1
    … Okay? But what you've tried to do clearly doesn't do that, and hence it won't work. The things that do mess with the kernel are therefore OS-specific, so your wish to not depend on the Windows APIs won't be fulfilled. – Asherah Jul 13 '12 at 04:42
  • Isn't there by any chance I could use the same code for two OS? Is that what you're saying? – Patrick Bassut Jul 13 '12 at 04:57
  • I'm saying there's no chance, because the operating systems are the ones who are giving you the interface to the real hardware (including the real memory). If you want to reach into another process's memory, then you need to deal with the thing that actually divided up the memory in the first place—that's the OS. – Asherah Jul 13 '12 at 06:31
2

It is possible to inject a function into another process but it is a little more involved than you think. The first thing is you need the proper length of the function you can do this by creating two functions.

static int realFunction() { ... }
static void realFunctionEnd() {}

Now when you copy the function over you do the length of:

realFunctionEnd - realFunction

This will give you the size. Now you cannot just call the other functions because as stated they are not guranteed to be at the same address in the other process, but you can assume that , I will assume windows, that kernal32.dll is at the same address so you can actually pass that to the realFunction when you create a remote thread.

Now, as to your real issue. What you need to do is to either inject a dll or copy a function over into the other process and then hook the function that you need to change. You can do this by copying another function over and making that code executable and then overwriting the first five bytes of the target function with a jump to your injected code, or you can do a proper detour type hook. In either case it should work. Or, you can find the offset into the function and patch it yourself by writing the proper op codes in place of the real code, such as a return of true.

Some kind of injection or patching is required to complete this, you have the basic idea, but there is a little more to it than you think at the moment. I have working code for windows to copy a function into another process, but I believe it is a good learning experience.

sean
  • 3,955
  • 21
  • 28
  • Do the functions has to be static? If yes, why? And how am I gonna user the second function as a "ending flag"? Why I can't guarantee that the address won't be the same in the other process? Is there any OS procedure that changes it? – Patrick Bassut Jul 13 '12 at 04:08
  • 1
    If I remember correctly the static keeps the functions in order, but again this is not guaranteed as it depends on the compiler, but for VC++ it did. The two functions occur one right after another in memory, being so their addresses are also one right after another. This property along with the fact that a function name is in essence a pointer to an address space you can treat it like a constant unsigned int. An OS may have Address Space Layout Randomization, or it just fails to set the exe image to its preferred base address. You can turn off ASLR, to keep the addresses similar. – sean Jul 13 '12 at 04:15
  • Got it. About measuring the function's size. Does that apply in any case? Cause when declaring the first function the next space in memory might be filled with something else. Thanks for the help. – Patrick Bassut Jul 13 '12 at 04:21
  • 1
    It is not guaranteed to be in order it is dependent on the compiler, there can be extra space in between but it ultimately doesn't matter as you are calling at the top of this allotted memory. – sean Jul 13 '12 at 04:24