Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7748687
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T10:50:56+00:00 2026-06-01T10:50:56+00:00

This has been pending for a long time in my list now. In brief

  • 0

This has been pending for a long time in my list now. In brief – I need to run mocked_dummy() in the place of dummy() ON RUN-TIME, without modifying factorial(). I do not care on the entry point of the software. I can add up any number of additional functions (but cannot modify code within /*---- do not modify ----*/).

Why do I need this?
To do unit tests of some legacy C modules. I know there are a lot of tools available around, but if run-time mocking is possible I can change my UT approach (add reusable components) make my life easier :).

Platform / Environment?
Linux, ARM, gcc.

Approach that I’m trying with?

  • I know GDB uses trap/illegal instructions for adding up breakpoints (gdb internals).
  • Make the code self modifiable.
  • Replace dummy() code segment with illegal instruction, and return as immediate next instruction.
  • Control transfers to trap handler.
  • Trap handler is a reusable function that reads from a unix domain socket.
  • Address of mocked_dummy() function is passed (read from map file).
  • Mock function executes.

There are problems going ahead from here. I also found the approach is tedious and requires good amount of coding, some in assembly too.

I also found, under gcc each function call can be hooked / instrumented, but again not very useful since the the function is intended to be mocked will anyway get executed.

Is there any other approach that I could use?

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

void mocked_dummy(void)
{
    printf("__%s__()\n",__func__);
}

/*---- do not modify ----*/
void dummy(void)
{
    printf("__%s__()\n",__func__);
}

int factorial(int num) 
{
    int                      fact = 1;
    printf("__%s__()\n",__func__);
    while (num > 1)
    {
        fact *= num;
        num--;
    }
    dummy();
    return fact;
}
/*---- do not modify ----*/

int main(int argc, char * argv[])
{
    int (*fp)(int) = atoi(argv[1]);
    printf("fp = %x\n",fp);
    printf("factorial of 5 is = %d\n",fp(5));
    printf("factorial of 5 is = %d\n",factorial(5));
    return 1;
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T10:50:58+00:00Added an answer on June 1, 2026 at 10:50 am

    This is a question I’ve been trying to answer myself. I also have the requirement that I want the mocking method/tools to be done in the same language as my application. Unfortunately this cannot be done in C in a portable way, so I’ve resorted to what you might call a trampoline or detour. This falls under the “Make the code self modifiable.” approach you mentioned above. This is were we change the actually bytes of a function at runtime to jump to our mock function.

    #include <stdio.h>
    #include <stdlib.h>
    
    // Additional headers
    #include <stdint.h> // for uint32_t
    #include <sys/mman.h> // for mprotect
    #include <errno.h> // for errno
    
    void mocked_dummy(void)
    {
        printf("__%s__()\n",__func__);
    }
    
    /*---- do not modify ----*/
    void dummy(void)
    {
        printf("__%s__()\n",__func__);
    }
    
    int factorial(int num) 
    {
        int                      fact = 1;
        printf("__%s__()\n",__func__);
        while (num > 1)
        {
            fact *= num;
            num--;
        }
        dummy();
        return fact;
    }
    /*---- do not modify ----*/
    
    typedef void (*dummy_fun)(void);
    
    void set_run_mock()
    {
        dummy_fun run_ptr, mock_ptr;
        uint32_t off;
        unsigned char * ptr, * pg;
    
        run_ptr = dummy;
        mock_ptr = mocked_dummy;
    
        if (run_ptr > mock_ptr) {
            off = run_ptr - mock_ptr;
            off = -off - 5;
        }
        else {
            off = mock_ptr - run_ptr - 5;
        }
    
        ptr = (unsigned char *)run_ptr;
    
        pg = (unsigned char *)(ptr - ((size_t)ptr % 4096));
        if (mprotect(pg, 5, PROT_READ | PROT_WRITE | PROT_EXEC)) {
            perror("Couldn't mprotect");
            exit(errno);
        }
    
        ptr[0] = 0xE9; //x86 JMP rel32
        ptr[1] = off & 0x000000FF;
        ptr[2] = (off & 0x0000FF00) >> 8;
        ptr[3] = (off & 0x00FF0000) >> 16;
        ptr[4] = (off & 0xFF000000) >> 24;
    }
    
    int main(int argc, char * argv[])
    {
        // Run for realz
        factorial(5);
    
        // Set jmp
        set_run_mock();
    
        // Run the mock dummy
        factorial(5);
    
        return 0;
    }
    

    Portability explanation…

    mprotect() – This changes the memory page access permissions so that we can actually write to memory that holds the function code. This isn’t very portable, and in a WINAPI env, you may need to use VirtualProtect() instead.

    The memory parameter for mprotect is aligned to the previous 4k page, this also can change from system to system, 4k is appropriate for vanilla linux kernel.

    The method that we use to jmp to the mock function is to actually put down our own opcodes, this is probably the biggest issue with portability because the opcode I’ve used will only work on a little endian x86 (most desktops). So this would need to be updated for each arch you plan to run on (which could be semi-easy to deal with in CPP macros.)

    The function itself has to be at least five bytes. The is usually the case because every function normally has at least 5 bytes in its prologue and epilogue.

    Potential Improvements…

    The set_mock_run() call could easily be setup to accept parameters for reuse. Also, you could save the five overwritten bytes from the original function to restore later in the code if you desire.

    I’m unable to test, but I’ve read that in ARM… you’d do similar but you can jump to an address (not an offset) with the branch opcode… which for an unconditional branch you’d have the first bytes be 0xEA and the next 3 bytes are the address.

    Chenz

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

This has been bugging me for a couple days now. A list has content
This has been frustrating me for a while now. I started developing a site
This has been confusing me for some time. With the advent of UTF-8 as
Desperately need help on this task; been hacking at it for a day now.
this has been an ongoing problem with me, ive been trying to make a
This has been a massive headache. We use Ning as a our platform for
This has been a rather problematic issue on numerous occasions. We have alot of
This has been driving me crazy for the past few minutes I have a
This has been one of the biggest obstacles in teaching new people ColdFusion. When
This has been driving me nuts. I keep getting the following exception System.InvalidOperationException: The

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.