Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle Large Bit Fields #51

Open
2 tasks done
t0rr3sp3dr0 opened this issue Apr 29, 2024 · 6 comments
Open
2 tasks done

Handle Large Bit Fields #51

t0rr3sp3dr0 opened this issue Apr 29, 2024 · 6 comments
Assignees
Labels
bug Something isn't working triage

Comments

@t0rr3sp3dr0
Copy link
Contributor

What happened?

We always set bit fields to unsigned int, but that fails when we have a bit field larger than 32 bits.

Width of bit-field 'i' (128 bits) exceeds the width of its type (32 bits)

How can we reproduce this?

Decompile this:

@implementation C : NSObject {
    __int128 i : 128;
}

@end

go-macho version

v1.1.208

Search

  • I did search for other open and closed issues before opening this

Code of Conduct

  • I agree to follow this project's Code of Conduct

Additional context

No response

@t0rr3sp3dr0 t0rr3sp3dr0 added bug Something isn't working triage labels Apr 29, 2024
@blacktop
Copy link
Owner

blacktop commented Apr 29, 2024

I noticed this as well. There's also the NSNumber (I think) ex you found, where VERY annoyingly the first bitfield field is encoded as b8 but the src says it's signed int x:8 etc

There's no way to tell that it's signed just how many bits/wide it is. (so no way to have a perfect decode)

@blacktop
Copy link
Owner

blacktop commented Apr 29, 2024

To solve this issue however is going to be kinda gross, where I'll have to parse ALL the properties or stucts fields etc and then go BACK to determine the orig size of int. Shouldn't be too hard, just gross

@t0rr3sp3dr0
Copy link
Contributor Author

It was NSDecimalNumber. Yeah, it sucks the encoded objc type is only b8.

  • ipsw Header:
@interface NSDecimalNumber : NSNumber {
    /* instance variables */
    unsigned int x :8 _exponent;
    unsigned int x :4 _length;
    unsigned int x :1 _isNegative;
    unsigned int x :1 _isCompact;
    unsigned int x :1 _reserved;
    unsigned int x :1 _hasExternalRefCount;
    unsigned int x :16 _refs;
    unsigned short * _mantissa;
}
  • Official Apple SDK Header:
@interface NSDecimalNumber : NSNumber {
@private
    signed   int _exponent:8;
    unsigned int _length:4;
    unsigned int _isNegative:1;
    unsigned int _isCompact:1;
    unsigned int _reserved:1;
    unsigned int _hasExternalRefCount:1;
    unsigned int _refs:16;
    unsigned short _mantissa[];
}

@t0rr3sp3dr0
Copy link
Contributor Author

We could technically omit the sign of the integer and let the user decide...

In the C programming language, the width of a bit-field cannot exceed the width of the underlying type, and WHETHER INT BIT-FIELDS THAT ARE NOT EXPLICITLY SIGNED OR UNSIGNED ARE SIGNED OR UNSIGNED IS IMPLEMENTATION-DEFINED. For example, int b:3; may have the range of values 0..7 or -4..3 in C, but only the latter choice is allowed in C++.

From: https://en.cppreference.com/w/cpp/language/bit_field

@t0rr3sp3dr0
Copy link
Contributor Author

This is interesting: https://github.com/apple-oss-distributions/clang/blob/rel/clang-800/src/tools/clang/lib/AST/ASTContext.cpp#L5536-L5550

I wished LLVM had stuck with the GNU version rather than the NeXT version...

@blacktop
Copy link
Owner

blacktop commented May 2, 2024

This is interesting: https://github.com/apple-oss-distributions/clang/blob/rel/clang-800/src/tools/clang/lib/AST/ASTContext.cpp#L5536-L5550

I wished LLVM had stuck with the GNU version rather than the NeXT version...

lol, yes, that's MUCH nicer 😞

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working triage
Projects
None yet
Development

No branches or pull requests

2 participants