0

I'm working on a dll that attaches to a program and reads some data from the target program. I do this by finding the struct address and casting that address to a pointer of the respective struct in my code.

Example:

class Structure {
   char pad_1[0x30];
   float val1;
   float val2
   char pad_2[0x20];
   Structure* next;
}

Here if I find the address of the structure to be 0x1234 I can just do (Structure*)0x1234 and I have access to it, notice that there are some padding values, those values I simply don't know what they are or I don't need them.

I want to write this struct in my code (for maintainability purposes) as following:

class Structure {
   Offset(0x30)
   float val1;
   float val2;

   Offset(0x58) /// 0x30 + 2x floats + 0x20 padding
   Structure* next;
}

This Offset macro should add padding automatically, basically with Offset(num) u specify the offset of the field in the class, this macro should add this padding automatically.

I have no idea if this is possible with C macros, right now I'm defining my models in YAML and using a python script to generate them, there are some disadvantages to this however...

  • Note that compiler can add padding by itself. You need inform compiler that you need packed structure (some compiler specific macros) and just insert dummy array of chars as custom padding. In standard C or C++ it is impossible. – Marek R Jun 23 '21 at 15:21
  • 1
    Nope, neither C nor C++ works this way. – Sam Varshavchik Jun 23 '21 at 15:22
  • Marek R, my problem is how do I insert these paddings easily with macros or something like that knowing at which offsets the fields are –  Jun 23 '21 at 15:23
  • Setting aside whether or not this is a good idea, what is wrong with your first example? After all, the `struct`s you are patching are unlikely to change much, – Paul Sanders Jun 23 '21 at 15:26
  • 1
    You could add static asserts to check offset of respective fields to be sure nothing gets broken. – Marek R Jun 23 '21 at 15:27
  • If I have a struct with many paddings and one of the first paddings shifts then all the subsequent paddings needs to be recalculated and updated. Speaking from experience since I made a similar project before, its a nightmare to maintain. I think ill stick with the code generation method if its not possible –  Jun 23 '21 at 15:30
  • You might be able to abuse the type system and unions by creating a really ugly massively nested anonymous union mess. One member of the union is a char array with the offset, the other the earlier contents of the struct. – 1201ProgramAlarm Jun 23 '21 at 16:42
  • @orenrevenge I'm not sure what you mean by *all the subsequent paddings needs to be recalculated*. Isn't that just what macro you want would introduce? – apple apple Jun 23 '21 at 17:11

3 Answers3

0

It seems to me, that what you want to do is to essentially make the macros expand into char arrays of given size. The only tricky thing here is to have unique names of the structure members, and you can achieve that using __LINE__ and double-step concatenation in a macro:

#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define OFFSET(size) char TOKENPASTE2(pad_, __LINE__)[size]

and use it the way you wanted. Note, that you get some cryptic structure member names, that are not visible from code but might be visible in IDE during development. I'm not sure if it's really more maintainable, I would just put there char arrays manually.

Original answer from: Creating C macro with ## and __LINE__ (token concatenation with positioning macro)

Kaznov
  • 1,035
  • 10
  • 17
  • in my example Offset(0x58) should yield char pad[0x20] but it will always yield pad[0x58] –  Jun 23 '21 at 16:41
  • @orenrevenge right, I didn't notice this part. To my knowledge, there is no way to do it then – Kaznov Jun 24 '21 at 08:46
0
Offset(0x58) /// 0x30 + 2x floats + 0x20 padding

It is not possible - you can't like "query" how much memory "was" used when still inside defining the type. The information is known after the type was defined. It is not possible in the C language.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
0

This is not something you solve with macro's, or structs.

High level, you want a tuple<padding<30>, float, float, padding<58>, void*>. That's not a std::tuple, but the idea is similar - you want a class template that calculates the various offsets, using your own rules.

MSalters
  • 173,980
  • 10
  • 155
  • 350