Calling Getsectiondata from Swift

Calling getsectiondata from Swift

The difference between the linked-to Objective-C code

void *ptr = getsectiondata(&_mh_execute_header, ...);

and your Swift translation

var header = _mh_execute_header
let localizationSection = getsectiondata(&header, ...)

is that the latter passes the address of a copy of the global
_mh_execute_header variable to the function, and apparently that
is not accepted. If you modify the Objective-C code to

struct mach_header_64 header = _mh_execute_header;
void *ptr = getsectiondata(&header, ...);

then it fails as well (and actually crashed in my test).

Now the problem is that _mh_execute_header is exposed to Swift
as a constant:

public let _mh_execute_header: mach_header_64

and one cannot take the address of a constant in Swift. One possible
workaround is to define

#import <mach-o/ldsyms.h>
static const struct mach_header_64 *mhExecHeaderPtr = &_mh_execute_header;

in the bridging header file, and then use it as

let localizationSection = getsectiondata(mhExecHeaderPtr, ...)

in Swift.


Another option is to lookup the symbol via dlopen/dlsym

import MachO

if let handle = dlopen(nil, RTLD_LAZY) {
defer { dlclose(handle) }

if let ptr = dlsym(handle, MH_EXECUTE_SYM) {
let mhExecHeaderPtr = ptr.assumingMemoryBound(to: mach_header_64.self)

var size: UInt = 0
let localizationSection = getsectiondata(
mhExecHeaderPtr,
"__LOCALIZATIONS",
"__base",
&size)

// ...
}
}

How to access properties/member of struct pointer in Swift

It's similar to c, where you would use the -> operator (libHeader->ncmds), requivalent to (*libHeader).ncmds. That is, first your reference the pointer to get to the mach_header_64 value, then you access its ncmds field.

In Swift, it's the exact same idea, with different syntax: libHeaver.pointee.ncmds

Crash reading bytes from getsectbyname

getsectbyname() does not adjust the section's address for ASLR. You should use getsectiondata() instead if your deployment target allows (first implemented in OS X 10.7, I think).

NSMultipleValuesMarker use of undeclared type in Swift 3

'is' is the type check operator to check whether an instance is of a certain subclass type. Use selection === NSMultipleValuesMarker to check if selection is NSMultipleValuesMarker.

swift tableview delegate method did not response in another class

It looks like tableView1Delegate has scope issue, please make sure it is declared as class instances and not inside function.

class YOUR_CONTROLLER {

var tableView1Delegate : xxxtableviewdelegate

func YOUR_FUNCTION {
tableView1 = xxxtableviewdelegate()
tableView1?.delegate = tableView1Delegate
tableView1?.dataSource = tableView1Delegate
}

}

CellProvider Closure never gets executed for UICollectionViewDiffableDataSource

It's because you're not appending your items anywhere, and so your snapshot is empty. When you append a section, you're only appending the section as an identifier. You are not appending the section and all its items.

See the documentation here.

How to parse private Objective-C specific Mach-O sections

Take a look at the definition of the GETSECT macro in a slightly newer version of the Objective-C runtime implementation. It looks like so:

#define GETSECT(name, type, sectname)                                   \
type *name(const header_info *hi, size_t *outCount) \
{ \
unsigned long byteCount = 0; \
type *data = (type *) \
getsectiondata(hi->mhdr, SEG_DATA, sectname, &byteCount); \
*outCount = byteCount / sizeof(type); \
return data; \
}

This tells us that each section is an array of items of type type.

It's used a few lines later to declare functions named _getObjc2ClassRefs and _getObjc2ClassList which read the two sections that you're interested in:

GETSECT(_getObjc2ClassRefs,           class_t *,       "__objc_classrefs");
GETSECT(_getObjc2ClassList, classref_t, "__objc_classlist");

So __objc_classrefs contains class_t *s, and __objc_classlist contains classref_ts. Interpreting those fields should be relatively self-explanatory.



Related Topics



Leave a reply



Submit