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 8265655
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 8, 20262026-06-08T04:52:53+00:00 2026-06-08T04:52:53+00:00

I’ve been trying to use ‘thunking’ so I can use member functions to legacy

  • 0

I’ve been trying to use ‘thunking’ so I can use member functions to legacy APIs which expects a C function. I’m trying to use a similar solution to this. This is my thunk structure so far:

struct Thunk
{
    byte mov;   // ↓
    uint value; // mov esp, 'value' <-- replace the return address with 'this' (since this thunk was called with 'call', we can replace the 'pushed' return address with 'this')

    byte call;  // ↓
    int offset; // call 'offset' <-- we want to return here for ESP alignment, so we use call instead of 'jmp'

    byte sub;   // ↓
    byte esp;   // ↓
    byte num;   // sub esp, 4 <-- pop the 'this' pointer from the stack

    //perhaps I should use 'ret' here as well/instead?
} __attribute__((packed));

The following code is a test of mine which uses this thunk structure (but it does not yet work):

#include <iostream>
#include <sys/mman.h>
#include <cstdio>

typedef unsigned char byte;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;

#include "thunk.h"

template<typename Target, typename Source>
inline Target brute_cast(const Source s)
{
    static_assert(sizeof(Source) == sizeof(Target));

    union { Target t; Source s; } u;
    u.s = s;
    return u.t;
}

void Callback(void (*cb)(int, int))
{
    std::cout << "Calling...\n";
    cb(34, 71);
    std::cout << "Called!\n";
}

struct Test
{
    int m_x = 15;

    void Hi(int x, int y)
    {
        printf("X: %d | Y: %d | M: %d\n", x, y, m_x);
    }
};

int main(int argc, char * argv[])
{
    std::cout << "Begin Execution...\n";

    Test test;

    Thunk * thunk = static_cast<Thunk*>(mmap(nullptr, sizeof(Thunk),
        PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0));

    thunk->mov = 0xBC; // mov esp
    thunk->value = reinterpret_cast<uint>(&test);

    thunk->call = 0xE8; // call
    thunk->offset = brute_cast<uint>(&Test::Hi) - reinterpret_cast<uint>(thunk);
    thunk->offset -= 10; // Adjust the relative call

    thunk->sub = 0x83; // sub
    thunk->esp = 0xEC; // esp
    thunk->num = 0x04; // 'num'

    // Call the function
    Callback(reinterpret_cast<void (*)(int, int)>(thunk));
    std::cout << "End execution\n";
}

If I use that code; I receive a segmentation fault within the Test::Hi function. The reason is obvious (once you analyze the stack in GDB) but I do not know how to fix this. The stack is not aligned properly.

The x argument contains garbage but the y argument contains the this pointer (see the Thunk code). That means the stack is misaligned by 8 bytes, but I still don’t know why this is the case. Can anyone tell why this is happening? x and y should contain 34 and 71 respectively.

NOTE: I’m aware of the fact that this is does not work in all scenarios (such as MI and VC++ thiscall convention) but I want to see if I can get this work, since I would benefit from it a lot!

EDIT: Obviously I also know that I can use static functions, but I see this more as a challenge…

  • 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-08T04:52:58+00:00Added an answer on June 8, 2026 at 4:52 am

    Suppose you have a standalone (non-member, or maybe static) cdecl function:

    void Hi_cdecl(int x, int y)
    {
        printf("X: %d | Y: %d | M: %d\n", x, y, m_x);
    }
    

    Another function calls it this way:

    push 71
    push 36
    push (return-address)
    call (address-of-hi)
    add esp, 8 (stack cleanup)
    

    You want to replace this by the following:

    push 71
    push 36
    push this
    push (return-address)
    call (address-of-hi)
    add esp, 4 (cleanup of this from stack)
    add esp, 8 (stack cleanup)
    

    For this, you have to read the return-address from the stack, push this, and then, push the return-address. And for the cleanup, add 4 (not subtract) to esp.

    Regarding the return address – since the thunk must do some cleanup after the callee returns, it must store the original return-address somewhere, and push the return-address of the cleanup part of the thunk. So, where to store the original return-address?

    • In a global variable – might be an acceptable hack (since you probably don’t need your solution to be reentrant)
    • On the stack – requires moving the whole block of parameters (using a machine-language equivalent of memmove), whose length is pretty much unknown

    Please also note that the resulting stack is not 16-byte-aligned; this can lead to crashes if the function uses certain types (those that require 8-byte and 16-byte alignment – the SSE ones, for example; also maybe double).

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

Sidebar

Related Questions

I am trying to understand how to use SyndicationItem to display feed which is
I have a jquery bug and I've been looking for hours now, I can't
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I'm trying to use string.replace('’','') to replace the dreaded weird single-quote character: ’ (aka
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I used javascript for loading a picture on my website depending on which small
Basically, what I'm trying to create is a page of div tags, each has
I would like to run a str_replace or preg_replace which looks for certain words
I want use html5's new tag to play a wav file (currently only supported
I am trying to render a haml file in a javascript response like so:

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.