CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/external/source/exploits/CVE-2016-4655/flatten-macho.m
Views: 11779
1
//
2
// main.m
3
// flatten-macho
4
//
5
// Created by qwertyoruiop on 4/6/17.
6
// Copyright © 2017 qwertyoruiop. All rights reserved.
7
//
8
9
#import <Foundation/Foundation.h>
10
#import <mach-o/loader.h>
11
#import <fcntl.h>
12
#import <unistd.h>
13
#import <sys/stat.h>
14
#import <sys/mman.h>
15
16
int main(int argc, const char * argv[]) {
17
if(argc != 3)
18
{
19
printf("usage: %s <input> <output>\n", argv[0]);
20
return -1;
21
}
22
int fd = open(argv[1], O_RDONLY);
23
int fd_w = open(argv[2], O_RDWR|O_CREAT|O_TRUNC, 0755);
24
25
char header[0x4000];
26
pread(fd, header, 0x4000, 0);
27
28
struct mach_header_64* mh = header;
29
uint64_t min = -1;
30
uint64_t max = 0;
31
struct load_command* lc = mh+1;
32
for (int i = 0; i < mh->ncmds; i++) {
33
if (lc->cmd == LC_SEGMENT_64)
34
{
35
struct segment_command_64* sg = lc;
36
if (strcmp(sg->segname, "__PAGEZERO") != 0) {
37
printf("segment %s\n", sg->segname);
38
if (sg->vmaddr < min) min = sg->vmaddr;
39
if (sg->vmaddr+sg->vmsize > max) max = sg->vmaddr+sg->vmsize;
40
}
41
}
42
lc = (((char*)lc)+lc->cmdsize);
43
}
44
45
printf("found base: %llx, max: %llx\n", min, max);
46
if(lseek(fd_w, max, SEEK_SET) == -1)
47
{
48
printf("seek failed\n");
49
return -1;
50
}
51
52
lc = mh+1;
53
for (int i = 0; i < mh->ncmds; i++) {
54
if (lc->cmd == LC_SEGMENT_64)
55
{
56
struct segment_command_64* sg = lc;
57
printf("mapping to %llx %llx %llx\n", sg->vmaddr, sg->fileoff, sg->filesize);
58
59
if (sg->filesize == 0) {
60
lc = (((char*)lc)+lc->cmdsize);
61
continue;
62
} // ignore pagezero
63
char* map = mmap(0, sg->vmsize, PROT_READ, MAP_ANON|MAP_PRIVATE, -1, 0);
64
if(mmap(map, sg->filesize, PROT_READ, MAP_FIXED|MAP_FILE|MAP_PRIVATE,fd,sg->fileoff) == MAP_FAILED)
65
{
66
printf("mmap failed\n");
67
return -1;
68
}
69
printf("seeking to %llx\n", sg->vmaddr-min);
70
lseek(fd_w, sg->vmaddr-min, SEEK_SET);
71
write(fd_w, map, sg->vmsize);
72
munmap(map, sg->vmsize);
73
}
74
lc = (((char*)lc)+lc->cmdsize);
75
}
76
77
return 0;
78
}
79
80
81