├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── ktrw_gdb_stub
├── Makefile
├── kernel_symbols
│ ├── iPhone10,1_17B102.txt
│ ├── iPhone10,1_17C54.txt
│ └── iPhone10,1_17F75.txt
└── source
│ ├── debug.c
│ ├── debug.h
│ ├── devicetree.c
│ ├── devicetree.h
│ ├── gdb_stub
│ ├── gdb_cpu.c
│ ├── gdb_cpu.h
│ ├── gdb_internal.c
│ ├── gdb_internal.h
│ ├── gdb_packets.c
│ ├── gdb_packets.h
│ ├── gdb_platform.c
│ ├── gdb_platform.h
│ ├── gdb_rsp.c
│ ├── gdb_rsp.h
│ ├── gdb_state.h
│ ├── gdb_stub.c
│ └── gdb_stub.h
│ ├── if_value.h
│ ├── jit_heap.c
│ ├── jit_heap.h
│ ├── kernel_extern.h
│ ├── ktrw.c
│ ├── page_table.c
│ ├── page_table.h
│ ├── primitives.c
│ ├── primitives.h
│ ├── third_party
│ ├── boot_args.h
│ └── kmod.h
│ ├── usb
│ ├── synopsys_otg.c
│ ├── synopsys_otg_regs.h
│ └── usb.h
│ ├── watchdog.c
│ └── watchdog.h
├── ktrw_kext_loader
├── Makefile
├── app
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── Info.plist
│ ├── ViewController.h
│ ├── ViewController.m
│ └── main.m
├── headers
│ ├── IOKitLib.h
│ └── mach_vm.h
├── kernel
│ ├── kernel_memory.c
│ ├── kernel_memory.h
│ ├── kernel_parameters.c
│ ├── kernel_parameters.h
│ ├── kernel_slide.c
│ ├── kernel_slide.h
│ ├── kernel_tasks.c
│ └── kernel_tasks.h
├── kernel_call
│ ├── kernel_call.c
│ ├── kernel_call.h
│ ├── kernel_call_7_a11.c
│ ├── kernel_call_7_a11.h
│ ├── kernel_call_parameters.c
│ └── kernel_call_parameters.h
├── kernel_patches
│ ├── kernel_patches.c
│ └── kernel_patches.h
├── kernel_symbols
│ ├── iPhone10,1_16C101.txt
│ ├── iPhone10,1_16G77.txt
│ └── iPhone10,6_16E227.txt
├── kext_load
│ ├── kext_load.c
│ ├── kext_load.h
│ ├── resolve_symbol.c
│ └── resolve_symbol.h
├── ktrr
│ ├── ktrr_bypass.c
│ ├── ktrr_bypass.h
│ ├── ktrr_bypass_parameters.c
│ └── ktrr_bypass_parameters.h
├── ktrw_kext_loader.entitlements
├── ktrw_kext_loader.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── ktrw_kext_loader.xcscheme
├── main.c
└── system
│ ├── bundle_path.c
│ ├── bundle_path.h
│ ├── log.c
│ ├── log.h
│ ├── map_file.c
│ ├── map_file.h
│ ├── parameters.h
│ ├── platform.c
│ ├── platform.h
│ ├── platform_match.c
│ └── platform_match.h
├── ktrw_usb_proxy
├── Makefile
└── source
│ └── ktrw_usb_proxy.c
├── misc
└── dbg_xnu.cfg.patch
├── pongo_kext_loader
├── Makefile
└── source
│ └── pongo_kext_loader.c
└── pongo_kextload
├── Makefile
└── source
├── pongo_kextload.c
└── third_party
└── pongo.h
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to Contribute
2 |
3 | We'd love to accept your patches and contributions to this project. There are
4 | just a few small guidelines you need to follow.
5 |
6 | ## Contributor License Agreement
7 |
8 | Contributions to this project must be accompanied by a Contributor License
9 | Agreement. You (or your employer) retain the copyright to your contribution;
10 | this simply gives us permission to use and redistribute your contributions as
11 | part of the project. Head over to to see
12 | your current agreements on file or to sign a new one.
13 |
14 | You generally only need to submit a CLA once, so if you've already submitted one
15 | (even if it was for a different project), you probably don't need to do it
16 | again.
17 |
18 | ## Code reviews
19 |
20 | All submissions, including submissions by project members, require review. We
21 | use GitHub pull requests for this purpose. Consult
22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
23 | information on using pull requests.
24 |
25 | ## Community Guidelines
26 |
27 | This project follows [Google's Open Source Community
28 | Guidelines](https://opensource.google.com/conduct/).
29 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | TARGET_DIRECTORIES = pongo_kext_loader pongo_kextload ktrw_gdb_stub ktrw_usb_proxy
2 |
3 | all: $(TARGET_DIRECTORIES)
4 |
5 | .PHONY: all $(TARGET_DIRECTORIES)
6 |
7 | $(TARGET_DIRECTORIES):
8 | $(MAKE) -C $@
9 |
10 | CLEAN_TARGET_DIRECTORIES = $(TARGET_DIRECTORIES:%=clean-%)
11 |
12 | clean: $(CLEAN_TARGET_DIRECTORIES)
13 |
14 | .PHONY: clean $(CLEAN_TARGET_DIRECTORIES)
15 |
16 | $(CLEAN_TARGET_DIRECTORIES):
17 | $(MAKE) -C $(@:clean-%=%) clean
18 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/Makefile:
--------------------------------------------------------------------------------
1 | TARGET = ktrw_gdb_stub.ikext
2 |
3 | ARCH = arm64
4 | SDK = iphoneos
5 | KTRW_VERSION = 0.1.0
6 | ACTIVATION_DELAY = 30
7 |
8 | SYSROOT := $(shell xcrun --sdk $(SDK) --show-sdk-path)
9 | ifeq ($(SYSROOT),)
10 | $(error Could not find SDK $(SDK))
11 | endif
12 | CLANG := $(shell xcrun --sdk $(SDK) --find clang)
13 | CC := $(CLANG) -isysroot $(SYSROOT) -arch $(ARCH)
14 |
15 | CFLAGS = -fno-builtin -fno-common -mkernel
16 | CFLAGS += -Isource
17 | CFLAGS += -O2
18 | CFLAGS += -Wall -Werror -Wpedantic -Wno-gnu -Wno-language-extension-token
19 | # TODO: -Wconversion
20 |
21 | DEFINES = -DKTRW_VERSION='"$(KTRW_VERSION)"' \
22 | -DKTRW_GDB_STUB_ACTIVATION_DELAY='$(ACTIVATION_DELAY)'
23 |
24 | LDFLAGS = -Xlinker -kext -nostdlib -Xlinker -fatal_warnings
25 |
26 | SOURCES = source/gdb_stub/gdb_cpu.c \
27 | source/gdb_stub/gdb_internal.c \
28 | source/gdb_stub/gdb_packets.c \
29 | source/gdb_stub/gdb_platform.c \
30 | source/gdb_stub/gdb_rsp.c \
31 | source/gdb_stub/gdb_stub.c \
32 | source/usb/synopsys_otg.c \
33 | source/debug.c \
34 | source/devicetree.c \
35 | source/jit_heap.c \
36 | source/ktrw.c \
37 | source/page_table.c \
38 | source/primitives.c \
39 | source/watchdog.c
40 |
41 | HEADERS = source/gdb_stub/gdb_cpu.h \
42 | source/gdb_stub/gdb_internal.h \
43 | source/gdb_stub/gdb_packets.h \
44 | source/gdb_stub/gdb_platform.h \
45 | source/gdb_stub/gdb_rsp.h \
46 | source/gdb_stub/gdb_state.h \
47 | source/gdb_stub/gdb_stub.h \
48 | source/third_party/boot_args.h \
49 | source/usb/synopsys_otg_regs.h \
50 | source/usb/usb.h \
51 | source/debug.h \
52 | source/devicetree.h \
53 | source/if_value.h \
54 | source/jit_heap.h \
55 | source/kernel_extern.h \
56 | source/page_table.h \
57 | source/primitives.h \
58 | source/watchdog.h
59 |
60 | $(TARGET): $(SOURCES) $(HEADERS)
61 | $(CC) $(CFLAGS) $(DEFINES) $(LDFLAGS) -o $@ $(SOURCES)
62 |
63 | symbols: $(TARGET)
64 | @nm -u $(TARGET)
65 |
66 | clean:
67 | rm -rf -- $(TARGET).$(ARCH).ld
68 | rm -f -- $(TARGET)
69 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/kernel_symbols/iPhone10,1_17B102.txt:
--------------------------------------------------------------------------------
1 | KERNELCACHE UUID: 6D59B3A0-4546-32CD-A399-FA9F24D99ED2
2 | DEVICE: iPhone10,1 17B102
3 | DEVICE: iPhone10,4 17B102
4 |
5 | __disable_preemption 0xFFFFFFF007CD06E4
6 | __enable_preemption 0xFFFFFFF007CD0710
7 | __mh_execute_header 0xFFFFFFF007004000
8 | _const_boot_args 0xFFFFFFF007906870
9 | _IOSleep 0xFFFFFFF0080F568C
10 | _kernel_map 0xFFFFFFF007905658
11 | _kernel_memory_allocate 0xFFFFFFF007C50AF4
12 | _kernel_thread_start 0xFFFFFFF007BFAC54
13 | _ml_nofault_copy 0xFFFFFFF007CD6CF8
14 | _panic 0xFFFFFFF0090329E4
15 | _paniclog_append_noflush 0xFFFFFFF007BD5698
16 | _thread_deallocate 0xFFFFFFF007BF93A0
17 | _vsnprintf 0xFFFFFFF007FE60E4
18 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/kernel_symbols/iPhone10,1_17C54.txt:
--------------------------------------------------------------------------------
1 | KERNELCACHE UUID: EB3BF781-4235-3F5E-8E77-B4C836D5F71F
2 | DEVICE: iPhone10,1 17C54
3 | DEVICE: iPhone10,4 17C54
4 |
5 | __disable_preemption 0xFFFFFFF007CD8BC4
6 | __enable_preemption 0xFFFFFFF007CD8BF0
7 | __mh_execute_header 0xFFFFFFF007004000
8 | _const_boot_args 0xFFFFFFF00790A870
9 | _IOSleep 0xFFFFFFF0080FC218
10 | _kernel_map 0xFFFFFFF007909658
11 | _kernel_memory_allocate 0xFFFFFFF007C58B6C
12 | _kernel_thread_start 0xFFFFFFF007C02C8C
13 | _ml_nofault_copy 0xFFFFFFF007CDF1D8
14 | _panic 0xFFFFFFF00903A9E4
15 | _paniclog_append_noflush 0xFFFFFFF007BDD6D0
16 | _thread_deallocate 0xFFFFFFF007C013D8
17 | _vsnprintf 0xFFFFFFF007FECB98
18 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/kernel_symbols/iPhone10,1_17F75.txt:
--------------------------------------------------------------------------------
1 | KERNELCACHE UUID: 15576917-FD0D-3A15-B52E-72D55A37D8E8
2 | DEVICE: iPhone10,1 17F75
3 | DEVICE: iPhone10,4 17F75
4 |
5 | __disable_preemption 0xFFFFFFF007D08CF0
6 | __enable_preemption 0xFFFFFFF007D08D20
7 | __mh_execute_header 0xFFFFFFF007004000
8 | _const_boot_args 0xFFFFFFF0079328C0
9 | _IOSleep 0xFFFFFFF008131198
10 | _kernel_map 0xFFFFFFF0079316a8
11 | _kernel_memory_allocate 0xFFFFFFF007C88CE0
12 | _kernel_thread_start 0xFFFFFFF007C33608
13 | _ml_nofault_copy 0xFFFFFFF007D0F574
14 | _panic 0xFFFFFFF00909EA08
15 | _paniclog_append_noflush 0xFFFFFFF007C0E170
16 | _thread_deallocate 0xFFFFFFF007C010AC
17 | _vsnprintf 0xFFFFFFF0080204E0
18 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/debug.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #include "debug.h"
21 |
22 | #include "page_table.h"
23 |
24 | // ---- Mapping the debug registers ---------------------------------------------------------------
25 |
26 | // 0x208010000, 0x208110000, 0x208210000, 0x208310000, 0x208410000, 0x208510000
27 | uint64_t cpu_register_base[MAX_CPU_COUNT];
28 |
29 | uint64_t external_debug_registers[MAX_CPU_COUNT];
30 | uint64_t dbgwrap_registers[MAX_CPU_COUNT];
31 |
32 | void
33 | map_debug_registers() {
34 | for (uint32_t cpu_id = 0; cpu_id < MAX_CPU_COUNT; cpu_id++) {
35 | if (external_debug_registers[cpu_id] != 0 || cpu_register_base[cpu_id] == 0) {
36 | continue;
37 | }
38 | external_debug_registers[cpu_id] = (uint64_t)
39 | ttbr0_map_io(cpu_register_base[cpu_id] + 0x00000, 0x1000);
40 | dbgwrap_registers[cpu_id] = (uint64_t)
41 | ttbr0_map_io(cpu_register_base[cpu_id] + 0x30000, 0x1000);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/debug.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef DEBUG__H_
21 | #define DEBUG__H_
22 |
23 | #include
24 |
25 | // The maximum number of CPUs.
26 | #define MAX_CPU_COUNT 6
27 |
28 | // The physical base address of the CPU registers. This should be initialized prior to mapping the
29 | // debug registers.
30 | extern uint64_t cpu_register_base[];
31 |
32 | // The memory-mapped CoreSight External Debug registers, per CPU.
33 | extern uint64_t external_debug_registers[];
34 |
35 | // The memory-mapped DBGWRAP registers, per CPU.
36 | extern uint64_t dbgwrap_registers[];
37 |
38 | #define rEDECR(cpu) *(volatile uint32_t *)(external_debug_registers[(cpu)] + 0x024)
39 | #define rEDWAR_lo(cpu) *(volatile uint32_t *)(external_debug_registers[(cpu)] + 0x030)
40 | #define rEDWAR_hi(cpu) *(volatile uint32_t *)(external_debug_registers[(cpu)] + 0x034)
41 | #define rDBGDTRRX(cpu) *(volatile uint32_t *)(external_debug_registers[(cpu)] + 0x080)
42 | #define rEDITR(cpu) *(volatile uint32_t *)(external_debug_registers[(cpu)] + 0x084)
43 | #define rEDSCR(cpu) *(volatile uint32_t *)(external_debug_registers[(cpu)] + 0x088)
44 | #define rDBGDTRTX(cpu) *(volatile uint32_t *)(external_debug_registers[(cpu)] + 0x08c)
45 | #define rEDRCR(cpu) *(volatile uint32_t *)(external_debug_registers[(cpu)] + 0x090)
46 | #define rOSLAR(cpu) *(volatile uint32_t *)(external_debug_registers[(cpu)] + 0x300)
47 | #define rEDPRSR(cpu) *(volatile uint32_t *)(external_debug_registers[(cpu)] + 0x314)
48 | #define rDBGBVR(cpu, n) *(volatile uint64_t *)(external_debug_registers[(cpu)] + 0x400 + 16 * n)
49 | #define rDBGBCR(cpu, n) *(volatile uint32_t *)(external_debug_registers[(cpu)] + 0x408 + 16 * n)
50 | #define rDBGWVR(cpu, n) *(volatile uint64_t *)(external_debug_registers[(cpu)] + 0x800 + 16 * n)
51 | #define rDBGWCR(cpu, n) *(volatile uint32_t *)(external_debug_registers[(cpu)] + 0x808 + 16 * n)
52 | #define rEDDFR_lo(cpu) *(volatile uint32_t *)(external_debug_registers[(cpu)] + 0xd28)
53 | #define rEDDFR_hi(cpu) *(volatile uint32_t *)(external_debug_registers[(cpu)] + 0xd2c)
54 | #define rEDLAR(cpu) *(volatile uint32_t *)(external_debug_registers[(cpu)] + 0xfb0)
55 | #define rEDLSR(cpu) *(volatile uint32_t *)(external_debug_registers[(cpu)] + 0xfb4)
56 |
57 | #define rDBGWRAP(cpu) *(volatile uint64_t *)(dbgwrap_registers[(cpu)] + 0x000)
58 |
59 | #define EDECR_SS (1 << 2)
60 |
61 | #define EDSCR_ITE (1 << 24)
62 | #define EDSCR_INTdis(b) (((b) & 0x3) << 22)
63 | #define EDSCR_TDA (1 << 21)
64 | #define EDSCR_HDE (1 << 14)
65 | #define EDSCR_ERR (1 << 6)
66 | #define EDSCR_STATUS (0x3f)
67 |
68 | #define EDRCR_CSE (1 << 2)
69 |
70 | #define EDPRSR_SDR (1 << 11)
71 | #define EDPRSR_HALTED (1 << 4)
72 |
73 | #define EDLSR_SLI (1 << 0)
74 | #define EDLSR_SLK (1 << 1)
75 |
76 | #define DBGWRAP_Halt (1uL << 31)
77 | #define DBGWRAP_Restart (1uL << 30)
78 | #define DBGWRAP_HaltAfterReset (1uL << 29) // EDECR.RCE ?
79 | #define DBGWRAP_CpuIsHalted (1uL << 28)
80 | #define DBGWRAP_DisableReset (1uL << 26) // EDPRCR.CORENPDRQ ?
81 |
82 | /*
83 | * map_debug_registers
84 | *
85 | * Description:
86 | * Map the debug registers.
87 | */
88 | void map_debug_registers(void);
89 |
90 | #endif
91 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/devicetree.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #include "devicetree.h"
21 |
22 | #include
23 |
24 | #include "primitives.h"
25 |
26 | // The format of a device tree node header.
27 | struct _devicetree_node {
28 | uint32_t n_properties;
29 | uint32_t n_children;
30 | };
31 |
32 | // The format of a device tree property header.
33 | struct _devicetree_property {
34 | char name[32];
35 | uint32_t size;
36 | uint8_t data[0];
37 | };
38 |
39 | // Parse a property and perform basic validation.
40 | static const struct _devicetree_property *
41 | parse_property(const uint8_t **p, const uint8_t *end) {
42 | // Parse the property header.
43 | const struct _devicetree_property *prop = (void *)*p;
44 | *p += sizeof(*prop);
45 | if (*p > end) {
46 | return NULL;
47 | }
48 | // Make sure the property name is null terminated.
49 | if (prop->name[sizeof(prop->name) - 1] != 0) {
50 | return NULL;
51 | }
52 | // Properties are padded to a multiple of 4 bytes.
53 | size_t padded_size = (prop->size + 0x3) & ~0x3;
54 | *p += padded_size;
55 | if (*p > end) {
56 | if (*p - padded_size + prop->size == end) {
57 | // If the very last property does not have the requisite
58 | // padding, that's okay.
59 | *p = end;
60 | } else {
61 | return NULL;
62 | }
63 | }
64 | return prop;
65 | }
66 |
67 | struct devicetree_node
68 | devicetree_find_node_by_property(struct devicetree devicetree,
69 | const char *key, const char *value) {
70 | const uint8_t *p = (const uint8_t *)devicetree.data;
71 | const uint8_t *end = p + devicetree.size;
72 | // We will do a "flat" scan of the devicetree, ignoring the hierarchy.
73 | size_t remaining_nodes = 1;
74 | for (;;) {
75 | // If we run out of data or believe there should be no more nodes left in the tree,
76 | // then we're done.
77 | if (p >= end || remaining_nodes == 0) {
78 | goto done;
79 | }
80 | // Parse the node header.
81 | const struct _devicetree_node *node = (void *)p;
82 | p += sizeof(*node);
83 | if (p > end) {
84 | goto done;
85 | }
86 | // We will linearly scan this node's children in subsequent loops.
87 | remaining_nodes += node->n_children;
88 | // Scan this node's properties, searching for a match.
89 | uint32_t n_properties = node->n_properties;
90 | for (uint32_t i = 0; i < n_properties; i++) {
91 | // Parse the property.
92 | const struct _devicetree_property *prop = parse_property(&p, end);
93 | if (prop == NULL) {
94 | goto done;
95 | }
96 | // Check if we have a property match. Both the property name and the
97 | // property value must match.
98 | int key_cmp = strcmp(prop->name, key);
99 | if (key_cmp == 0) {
100 | int value_cmp = strncmp((char *)prop->data, value, prop->size);
101 | if (value_cmp == 0) {
102 | return (struct devicetree_node) { node, end };
103 | }
104 | }
105 | }
106 | // Done with this node.
107 | remaining_nodes -= 1;
108 | }
109 | done:
110 | return (struct devicetree_node) { NULL, NULL };
111 | }
112 |
113 | struct devicetree_property
114 | devicetree_node_get_property(struct devicetree_node node0, const char *key) {
115 | const uint8_t *p = (void *)node0.data;
116 | const uint8_t *end = (void *)node0.end;
117 | // Parse the node header.
118 | const struct _devicetree_node *node = (void *)p;
119 | p += sizeof(*node);
120 | if (p > end) {
121 | goto done;
122 | }
123 | // Scan this node's properties, searching for a match.
124 | uint32_t n_properties = node->n_properties;
125 | for (uint32_t i = 0; i < n_properties; i++) {
126 | // Parse the property.
127 | const struct _devicetree_property *prop = parse_property(&p, end);
128 | if (prop == NULL) {
129 | goto done;
130 | }
131 | // Check if we have a property match.
132 | int key_cmp = strcmp(prop->name, key);
133 | if (key_cmp == 0) {
134 | return (struct devicetree_property) { prop->data, prop->size };
135 | }
136 | }
137 | done:
138 | return (struct devicetree_property) { NULL, 0 };
139 | }
140 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/devicetree.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef DEVICETREE__H_
21 | #define DEVICETREE__H_
22 |
23 | #include
24 | #include
25 |
26 | // A flattened device tree.
27 | struct devicetree {
28 | const void *data;
29 | size_t size;
30 | };
31 |
32 | // A device tree node header. Treat this type as opaque.
33 | struct devicetree_node {
34 | const void *data;
35 | const void *end;
36 | };
37 |
38 | // A device tree property's data.
39 | struct devicetree_property {
40 | const void *data;
41 | size_t size;
42 | };
43 |
44 | /*
45 | * devicetree_find_node_by_property
46 | *
47 | * Description:
48 | * Find a device tree node with a property with the specified property name and string value.
49 | */
50 | struct devicetree_node devicetree_find_node_by_property(struct devicetree devicetree,
51 | const char *key, const char *value);
52 |
53 | /*
54 | * devicetree_node_valid
55 | *
56 | * Description:
57 | * Checks whether a returned devicetree_node represents a valid node.
58 | */
59 | static inline bool
60 | devicetree_node_valid(struct devicetree_node node) {
61 | return node.data != NULL;
62 | }
63 |
64 | /*
65 | * devicetree_node_get_property
66 | *
67 | * Description:
68 | * Get the value of the specified property of a device tree node.
69 | */
70 | struct devicetree_property devicetree_node_get_property(struct devicetree_node node,
71 | const char *key);
72 |
73 | #endif
74 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/gdb_stub/gdb_cpu.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #include "gdb_cpu.h"
21 |
22 | #include "gdb_state.h"
23 |
24 | // ---- Checking CPU state ------------------------------------------------------------------------
25 |
26 | bool
27 | valid_cpu_id(int cpu_id) {
28 | return (0 <= cpu_id && cpu_id < CPU_COUNT && ((1 << cpu_id) & gdb.cpu_mask));
29 | }
30 |
31 | bool
32 | cpu_is_halted(int cpu_id) {
33 | // The cpu_id must be between 0 and CPU_COUNT - 1.
34 | uint32_t cpu_bit = 1 << cpu_id;
35 | return ((gdb.halted & cpu_bit) && (gdb.cpu_mask & cpu_bit));
36 | }
37 |
38 | bool
39 | cpu_is_running(int cpu_id) {
40 | // The cpu_id must be between 0 and CPU_COUNT - 1.
41 | uint32_t cpu_bit = 1 << cpu_id;
42 | return (!(gdb.halted & cpu_bit) && (gdb.cpu_mask & cpu_bit));
43 | }
44 |
45 | // ---- Interrupting and resuming CPUs ------------------------------------------------------------
46 |
47 | // Call this function just after resuming a CPU to update internal state.
48 | static void
49 | gdb_cpu_resumed(int cpu_id) {
50 | gdb.halted &= ~(1 << cpu_id);
51 | gdb.cpu_debug[cpu_id].halted_watchpoint = INVALID_ADDRESS;
52 | gdb.cpu_debug[cpu_id].state = CPU_STATE_RUNNING;
53 | }
54 |
55 | void
56 | gdb_interrupt_cpu(int cpu_id) {
57 | if (cpu_is_running(cpu_id)) {
58 | gdb_stub_interrupt_cpu(cpu_id);
59 | }
60 | }
61 |
62 | void
63 | gdb_resume_cpu(int cpu_id) {
64 | if (cpu_is_halted(cpu_id)) {
65 | gdb_stub_resume_cpu(cpu_id);
66 | gdb_cpu_resumed(cpu_id);
67 | }
68 | }
69 |
70 | void
71 | gdb_interrupt() {
72 | for (int cpu_id = 0; cpu_id < CPU_COUNT; cpu_id++) {
73 | if (valid_cpu_id(cpu_id)) {
74 | gdb_interrupt_cpu(cpu_id); // Only if running.
75 | }
76 | }
77 | }
78 |
79 | void
80 | gdb_resume() {
81 | for (int cpu_id = 0; cpu_id < CPU_COUNT; cpu_id++) {
82 | if (valid_cpu_id(cpu_id)) {
83 | gdb_resume_cpu(cpu_id); // Only if halted.
84 | }
85 | }
86 | }
87 |
88 | void
89 | gdb_step_cpu(int cpu_id) {
90 | if (cpu_is_halted(cpu_id)) {
91 | gdb_stub_step_cpu(cpu_id);
92 | gdb_cpu_resumed(cpu_id);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/gdb_stub/gdb_cpu.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef GDB_CPU__H_
21 | #define GDB_CPU__H_
22 |
23 | #include
24 | #include
25 | #include
26 |
27 | // ---- Checking CPU state ------------------------------------------------------------------------
28 |
29 | /*
30 | * valid_cpu_id
31 | *
32 | * Description:
33 | * Returns true if the CPU ID is valid.
34 | */
35 | bool valid_cpu_id(int cpu_id);
36 |
37 | /*
38 | * cpu_is_halted
39 | *
40 | * Description:
41 | * Returns true if the specified CPU is halted.
42 | */
43 | bool cpu_is_halted(int cpu_id);
44 |
45 | /*
46 | * cpu_is_running
47 | *
48 | * Description:
49 | * Returns true if the specified CPU is running.
50 | */
51 | bool cpu_is_running(int cpu_id);
52 |
53 | // ---- Interrupting and resuming CPUs ------------------------------------------------------------
54 |
55 | /*
56 | * gdb_interrupt_cpu
57 | *
58 | * Description:
59 | * Asynchronously interrupt a CPU, if it is running.
60 | */
61 | void gdb_interrupt_cpu(int cpu_id);
62 |
63 | /*
64 | * gdb_resume_cpu
65 | *
66 | * Description:
67 | * Asynchronously resume a CPU, if it is halted.
68 | */
69 | void gdb_resume_cpu(int cpu_id);
70 |
71 | /*
72 | * gdb_interrupt
73 | *
74 | * Description:
75 | * Asynchronously interrupt all running CPUs.
76 | */
77 | void gdb_interrupt(void);
78 |
79 | /*
80 | * gdb_resume
81 | *
82 | * Description:
83 | * Asynchronously resume all halted CPUs.
84 | */
85 | void gdb_resume(void);
86 |
87 | /*
88 | * gdb_step_cpu
89 | *
90 | * Description:
91 | * Asynchronously single-step a CPU, if it is halted.
92 | */
93 | void gdb_step_cpu(int cpu_id);
94 |
95 | #endif
96 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/gdb_stub/gdb_internal.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #include "gdb_internal.h"
21 |
22 | #include
23 |
24 | #include "gdb_rsp.h"
25 | #include "kernel_extern.h"
26 |
27 | // ---- Kernel symbols ----------------------------------------------------------------------------
28 |
29 | KERNEL_EXTERN int vsnprintf(char *buf, size_t size, const char *fmt, va_list ap);
30 |
31 | // ---- Formatting functions ----------------------------------------------------------------------
32 |
33 | int
34 | hex_digit(char ch) {
35 | if ('0' <= ch && ch <= '9') {
36 | return ch - '0';
37 | } else if ('a' <= ch && ch <= 'f') {
38 | return ch - 'a' + 0xa;
39 | } else if ('A' <= ch && ch <= 'F') {
40 | return ch - 'A' + 0xa;
41 | }
42 | return -1;
43 | }
44 |
45 | const char hex_char[16] = "0123456789abcdef";
46 |
47 | void
48 | vsnprintf_cat(char *buffer, size_t size, char **cursor, const char *format, va_list ap) {
49 | // Write the formatted data to a stack buffer. This allows us to skip the whole
50 | // null-terminator deal altogether.
51 | char src_buffer[GDB_RSP_MAX_PACKET_SIZE + 1];
52 | int len = vsnprintf(src_buffer, sizeof(src_buffer), format, ap);
53 | size_t written = len;
54 | // TODO: Ensure that no single print atom takes too much space! The vsnprintf() function
55 | // doesn't give us this flexibility, so we'll just silently drop characters :( In this
56 | // hack, if a single atom is larger than the source buffer size, we pretend that the atom
57 | // exactly filled the source buffer. Doing it this way (rather than only truncating if the
58 | // atom actually shows up in the output buffer) allows for consistency when windowing a
59 | // generated output string.
60 | if (written > sizeof(src_buffer)) {
61 | written = sizeof(src_buffer);
62 | }
63 | // Get copy parameters.
64 | char *dst = *cursor;
65 | char *src = src_buffer;
66 | size_t src_size = written;
67 | // Handle the case where the cursor is before the buffer so we need to discard some
68 | // characters from the source.
69 | if (dst < buffer) {
70 | size_t skip = buffer - dst;
71 | // Only skip up to the size of the source.
72 | if (skip >= src_size) {
73 | skip = src_size;
74 | }
75 | dst += skip;
76 | src += skip;
77 | src_size -= skip;
78 | }
79 | // Copy into dst as long as we're within the bounds of the output buffer and up to the size
80 | // of the source.
81 | if (buffer <= dst && dst < buffer + size) {
82 | size_t dst_size = buffer + size - dst;
83 | size_t copy_size = (dst_size < src_size ? dst_size : src_size);
84 | for (size_t i = 0; i < copy_size; i++) {
85 | dst[i] = src[i];
86 | }
87 | }
88 | // Update the cursor. Even if we exited the copy loop early, we update the cursor past the
89 | // ends of the buffer as if the whole source were copied.
90 | *cursor = dst + src_size;
91 | }
92 |
93 | void
94 | snprintf_cat(char *buffer, size_t size, char **cursor, const char *format, ...) {
95 | va_list ap;
96 | va_start(ap, format);
97 | vsnprintf_cat(buffer, size, cursor, format, ap);
98 | va_end(ap);
99 | }
100 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/gdb_stub/gdb_internal.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef GDB_INTERNAL__H_
21 | #define GDB_INTERNAL__H_
22 |
23 | #include
24 | #include
25 | #include
26 |
27 | /*
28 | * hex_digit
29 | *
30 | * Description:
31 | * Convert a character representing a hexadecimal digit to its numeric value or -1.
32 | */
33 | int hex_digit(char ch);
34 |
35 | /*
36 | * hex_char
37 | *
38 | * Description:
39 | * A table converting an integer between 0 and 15 to the corresponding hexadecimal digit.
40 | */
41 | extern const char hex_char[16];
42 |
43 | /*
44 | * snprintf_cat
45 | *
46 | * Description:
47 | * Print a formatted string to a buffer without null-terminating. The cursor specifies where
48 | * in or before the buffer printing should start. On return, cursor is updated to point to
49 | * where in or before the buffer printing would have ended if the buffer were infinite in both
50 | * directions. Only formatted data that actually falls within the true bounds of the buffer
51 | * will actually be written.
52 | *
53 | * Due to the current implementation of this function, correct behavior is only guaranteed if
54 | * at most 1024 characters are printed in a single call.
55 | */
56 | void snprintf_cat(char *buffer, size_t size, char **cursor, const char *format, ...);
57 |
58 | /*
59 | * vsnprintf_cat
60 | *
61 | * Description:
62 | * See snprintf_cat().
63 | */
64 | void vsnprintf_cat(char *buffer, size_t size, char **cursor, const char *format, va_list ap);
65 |
66 | #endif
67 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/gdb_stub/gdb_packets.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef GDB_PACKETS__H_
21 | #define GDB_PACKETS__H_
22 |
23 | #include
24 | #include
25 |
26 | /*
27 | * gdb_process_packet
28 | *
29 | * Description:
30 | * Handle a GDB RSP packet and send any replies. The supplied data buffer is used both for
31 | * parsing the request and building the reply, so it must be of capacity
32 | * GDB_RSP_MAX_PACKET_SIZE.
33 | */
34 | void gdb_process_packet(void *data, size_t size);
35 |
36 | /*
37 | * gdb_process_cpu_halts
38 | *
39 | * Description:
40 | * Handle any CPU halts and send any replies.
41 | */
42 | void gdb_process_cpu_halts(uint32_t halted_mask);
43 |
44 | #endif
45 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/gdb_stub/gdb_platform.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef GDB_PLATFORM__H_
21 | #define GDB_PLATFORM__H_
22 |
23 | #include
24 |
25 | // The maximum number of supported CPUs. The actual number of CPUs may be less than this.
26 | #define CPU_COUNT 6
27 |
28 | // The packed register definitions. This is the struct used to transfer registers between GDB and
29 | // the stub.
30 | struct __attribute__((packed)) gdb_registers {
31 | union {
32 | uint64_t x;
33 | uint32_t w;
34 | } x[31];
35 | uint64_t sp;
36 | uint64_t pc;
37 | uint32_t cpsr;
38 | union {
39 | uint64_t q[2];
40 | double d;
41 | float s;
42 | } v[32];
43 | uint32_t fpsr;
44 | uint32_t fpcr;
45 | };
46 |
47 | // A type for register IDs.
48 | typedef uint16_t reg_id_t;
49 |
50 | // An invalid register ID.
51 | #define INVALID_REG_ID ((reg_id_t)(-1))
52 |
53 | // Information describing a register to GDB.
54 | struct gdb_register_info {
55 | const char *name; // The register's name.
56 | const char *altname; // An alternative name for the register.
57 | uint8_t generic; // The GDB generic name of this register.
58 | uint8_t type; // The GDB type of this register.
59 | uint8_t encoding; // The GDB encoding of this register.
60 | uint8_t format; // The GDB format of this register.
61 | uint8_t group; // The GDB group of this register.
62 | uint8_t set; // The register set to which this register belongs.
63 | uint16_t offset; // The offset in the struct gdb_registers.
64 | uint16_t bitsize; // The size of this register in bits.
65 | reg_id_t ehframe_reg; // The exception handler frame register number.
66 | reg_id_t dwarf_reg; // The DWARF register number.
67 | reg_id_t value_regs[4]; // A list of registers that contain this register.
68 | reg_id_t invalidate_regs[4]; // A list of registers to invalidate if this one is set.
69 | };
70 |
71 | // The list of gdb_register_info structs.
72 | extern const struct gdb_register_info gdb_register_info[];
73 | extern const unsigned gdb_register_count;
74 |
75 | // Lookup tables for the string values of the generic, type, encoding, format, and group fields.
76 | extern const char *const gdb_register_generic_name[];
77 | extern const char *const gdb_register_type_name[];
78 | extern const char *const gdb_register_encoding_name[];
79 | extern const char *const gdb_register_format_name[];
80 | extern const char *const gdb_register_group_name[];
81 |
82 | // Information describing a register set to GDB.
83 | struct gdb_register_set_info {
84 | const char *description;
85 | };
86 |
87 | // The list of register sets.
88 | extern const struct gdb_register_set_info gdb_register_set_info[];
89 | extern const unsigned gdb_register_set_count;
90 |
91 | #endif
92 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/gdb_stub/gdb_rsp.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef GDB_RSP__H_
21 | #define GDB_RSP__H_
22 |
23 | #include
24 | #include
25 | #include
26 |
27 | // The maximum size of the data in a packet. This is calculated such that it is big enough to hold
28 | // the "g" packet (788 bytes of register data hex-encoded to a 0x628 byte packet) but small enough
29 | // that it is guaranteed that the RSP ACK and RSP-encoded packet will still fit within the
30 | // 0x1000 byte USB transport buffer.
31 | #define GDB_RSP_MAX_PACKET_SIZE 0x700
32 |
33 | /*
34 | * gdb_rsp_send_packet
35 | *
36 | * Description:
37 | * Send a packet to GDB.
38 | */
39 | void gdb_rsp_send_packet(const void *data, size_t size);
40 |
41 | /*
42 | * gdb_rsp_send_notification
43 | *
44 | * Description:
45 | * Send a notification packet to GDB.
46 | */
47 | void gdb_rsp_send_notification(const void *data, size_t size);
48 |
49 | /*
50 | * gdb_rsp_receive_packet
51 | *
52 | * Description:
53 | * Receive a packet from GDB.
54 | */
55 | bool gdb_rsp_receive_packet(void *data, size_t *size);
56 |
57 | #endif
58 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/gdb_stub/gdb_state.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef GDB_STATE__H_
21 | #define GDB_STATE__H_
22 |
23 | #include
24 |
25 | #include "gdb_stub.h"
26 |
27 | // ---- Definitions -------------------------------------------------------------------------------
28 |
29 | // An identifier for an invalid CPU. -1 is reserved to mean "all CPUs" or "unknown".
30 | #define INVALID_CPU (-2)
31 |
32 | // An invalid address.
33 | #define INVALID_ADDRESS ((uint64_t)(-1))
34 |
35 | // The possible CPU states.
36 | enum {
37 | CPU_STATE_RUNNING,
38 | CPU_STATE_HALTED,
39 | CPU_STATE_HALTED_HARDWARE_BREAKPOINT,
40 | CPU_STATE_HALTED_HARDWARE_WATCHPOINT,
41 | CPU_STATE_HALTED_SINGLE_STEP,
42 | };
43 |
44 | // A struct holding the GDB stub's state.
45 | struct gdb_stub_state {
46 | // The mask of available CPUs being debugged.
47 | uint32_t cpu_mask;
48 | // The mask of CPUs currently halted.
49 | uint32_t halted;
50 | // The current CPU.
51 | int current_cpu;
52 | // CPU debug state.
53 | struct {
54 | // The current CPU state. This indicates why the CPU is halted.
55 | int state;
56 | // The watchpoint address for which this CPU has halted. If INVALID_ADDRESS, then
57 | // the CPU is not currently halted because of a watchpoint.
58 | uint64_t halted_watchpoint;
59 | } cpu_debug[6];
60 | // The mask of CPUs that have just halted and need processing.
61 | uint32_t process_halted;
62 | // State for all-stop mode.
63 | struct {
64 | // True if GDB sent us a packet that requires we send a stop-reply, but we've
65 | // deferred sending the reply waiting for the appropriate stop to occur.
66 | bool stop_reply_deferred;
67 | // The first CPU that generated an "interesting" stop event (breakpoint or
68 | // watchpoint). This is what we'll try to report to LLDB, since reporting a stop
69 | // event for the current CPU when nothing is happening there seems to confuse LLDB
70 | // and make it loop single-stepping.
71 | int first_stop;
72 | } all_stop;
73 | // State for non-stop mode.
74 | struct {
75 | // Whether non-stop mode is currently enabled.
76 | bool enabled;
77 | // The mask of CPUs that GDB has confirmed it knows are halted.
78 | uint32_t stopped;
79 | // A mask of CPUs still left to report in non-stop mode.
80 | uint32_t queue;
81 | // A mask for the CPU for which there is an outstanding stop notification/packet
82 | // that has not yet been confirmed by a "vStopped" packet. This will be OR'd into
83 | // stopped once GDB ack's the packet.
84 | uint32_t pending;
85 | } non_stop;
86 | // Whether to send error strings with error packets. Controlled by QEnableErrorStrings.
87 | bool error_strings;
88 | // Whether to include a list of threads in stop reply packets. Controlled by
89 | // QListThreadsInStopReply.
90 | bool list_threads_in_stop_reply;
91 | // The main executable (kernel) Mach-O.
92 | const struct mach_header_64 *mach_header;
93 | // The number of available hardware watchpoints. We only need this for the
94 | // qWatchpointSupportInfo packet, which in turn is only needed so LLDB will respect
95 | // watchpoint_exceptions_received:before, which is needed so that LLDB will correctly
96 | // handle watchpoints.
97 | unsigned hardware_watchpoint_count;
98 | };
99 |
100 | // The GDB state.
101 | extern struct gdb_stub_state gdb;
102 |
103 | #endif
104 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/gdb_stub/gdb_stub.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #include "gdb_stub.h"
21 |
22 | #include
23 |
24 | #include "gdb_internal.h"
25 | #include "gdb_packets.h"
26 | #include "gdb_rsp.h"
27 | #include "gdb_state.h"
28 |
29 | // Define the main GDB state.
30 | struct gdb_stub_state gdb;
31 |
32 | void
33 | gdb_stub_init(uint32_t cpu_mask, uint32_t halted_mask) {
34 | halted_mask &= cpu_mask;
35 | gdb.cpu_mask = cpu_mask;
36 | gdb.halted = halted_mask;
37 | gdb.current_cpu = -1; // No current CPU.
38 | for (int cpu_id = 0; cpu_id < CPU_COUNT; cpu_id++) {
39 | gdb.cpu_debug[cpu_id].halted_watchpoint = INVALID_ADDRESS;
40 | int state = CPU_STATE_RUNNING;
41 | if (halted_mask & (1 << cpu_id)) {
42 | state = CPU_STATE_HALTED;
43 | }
44 | gdb.cpu_debug[cpu_id].state = state;
45 | }
46 | gdb.process_halted = 0;
47 | gdb.all_stop.stop_reply_deferred = false;
48 | gdb.all_stop.first_stop = INVALID_CPU;
49 | gdb.non_stop.enabled = false;
50 | gdb.non_stop.stopped = 0;
51 | gdb.non_stop.queue = 0;
52 | gdb.non_stop.pending = 0;
53 | gdb.error_strings = false;
54 | gdb.list_threads_in_stop_reply = false;
55 | gdb.mach_header = NULL;
56 | gdb.hardware_watchpoint_count = 0;
57 | }
58 |
59 | void
60 | gdb_stub_set_mach_header(const struct mach_header_64 *mach_header) {
61 | gdb.mach_header = mach_header;
62 | }
63 |
64 | void
65 | gdb_stub_set_hardware_watchpoint_count(unsigned hardware_watchpoint_count) {
66 | gdb.hardware_watchpoint_count = hardware_watchpoint_count;
67 | }
68 |
69 | // Record that a halt has taken place.
70 | static void
71 | gdb_stub_record_halt(int cpu_id) {
72 | gdb.halted |= (1 << cpu_id);
73 | gdb.process_halted |= (1 << cpu_id);
74 | // If we are in all-stop mode, and we have a deferred stop reply, and this is the first
75 | // stop we've observed, record it and switch to this CPU.
76 | if (!gdb.non_stop.enabled
77 | && gdb.all_stop.stop_reply_deferred
78 | && gdb.all_stop.first_stop == INVALID_CPU) {
79 | gdb.all_stop.first_stop = cpu_id;
80 | gdb.current_cpu = cpu_id;
81 | }
82 | }
83 |
84 | void
85 | gdb_stub_hit_hardware_breakpoint(int cpu_id) {
86 | gdb_stub_record_halt(cpu_id);
87 | gdb.cpu_debug[cpu_id].state = CPU_STATE_HALTED_HARDWARE_BREAKPOINT;
88 | }
89 |
90 | void
91 | gdb_stub_hit_hardware_watchpoint(int cpu_id, uint64_t address) {
92 | gdb_stub_record_halt(cpu_id);
93 | gdb.cpu_debug[cpu_id].halted_watchpoint = address;
94 | gdb.cpu_debug[cpu_id].state = CPU_STATE_HALTED_HARDWARE_WATCHPOINT;
95 | }
96 |
97 | void
98 | gdb_stub_did_step(int cpu_id) {
99 | gdb_stub_record_halt(cpu_id);
100 | gdb.cpu_debug[cpu_id].state = CPU_STATE_HALTED_SINGLE_STEP;
101 | }
102 |
103 | void
104 | gdb_stub_did_halt(int cpu_id) {
105 | gdb_stub_record_halt(cpu_id);
106 | gdb.cpu_debug[cpu_id].state = CPU_STATE_HALTED;
107 | }
108 |
109 | void
110 | gdb_stub_process_halts(uint32_t halted_mask) {
111 | if (halted_mask != gdb.halted) {
112 | // If we ever get out-of-sync, send a debugging message. This will likely break the
113 | // connection with the debugger.
114 | gdb_stub_log("%s: halted_mask(%x) != gdb.halted(%x)",
115 | __func__, halted_mask, gdb.halted);
116 | }
117 | if (gdb.process_halted != 0) {
118 | gdb_process_cpu_halts(gdb.process_halted);
119 | gdb.process_halted = 0;
120 | }
121 | }
122 |
123 | void
124 | gdb_stub_packet() {
125 | char packet[GDB_RSP_MAX_PACKET_SIZE];
126 | size_t size;
127 | // Try to receive the packet.
128 | bool ok = gdb_rsp_receive_packet(packet, &size);
129 | if (!ok) {
130 | return;
131 | }
132 | // Dispatch the packet to the appropriate handler.
133 | gdb_process_packet(packet, size);
134 | }
135 |
136 | void
137 | gdb_stub_log(const char *message, ...) {
138 | char buffer[GDB_RSP_MAX_PACKET_SIZE];
139 | char *p = buffer;
140 | va_list ap;
141 | va_start(ap, message);
142 | vsnprintf_cat(buffer, sizeof(buffer), &p, message, ap);
143 | va_end(ap);
144 | gdb_stub_serial_write(buffer, p - buffer);
145 | }
146 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/gdb_stub/gdb_stub.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef GDB_STUB__H_
21 | #define GDB_STUB__H_
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | // ---- Platform configuration --------------------------------------------------------------------
29 |
30 | #include "gdb_platform.h"
31 |
32 | // ---- Functions needed by the GDB stub ----------------------------------------------------------
33 |
34 | // Reset state to prepare for a new connection.
35 | void gdb_stub_reset_state(void);
36 |
37 | // Read any pending data sent from GDB to the GDB stub.
38 | size_t gdb_stub_serial_read(void *data, size_t size);
39 |
40 | // Write data generated by the GDB stub out to GDB.
41 | size_t gdb_stub_serial_write(const void *data, size_t size);
42 |
43 | // Called when the GDB stub wants to set or clear a hardware breakpoint.
44 | bool gdb_stub_set_hardware_breakpoint(uint64_t address);
45 | bool gdb_stub_clear_hardware_breakpoint(uint64_t address);
46 |
47 | // Called when the GDB stub wants to set or clear a hardware watchpoint. The type parameter
48 | // specifies the type of watchpoint: 'r' for read, 'w' for write, or 'a' for access.
49 | bool gdb_stub_set_hardware_watchpoint(uint64_t address, size_t size, char type);
50 | bool gdb_stub_clear_hardware_watchpoint(uint64_t address, size_t size, char type);
51 |
52 | // Called when the GDB stub wants to interrupt the specified CPU. The function should not wait for
53 | // the CPU to halt.
54 | void gdb_stub_interrupt_cpu(int cpu_id);
55 |
56 | // Called when the GDB stub wants to resume the specified CPU. The function should not wait for the
57 | // CPU to resume.
58 | void gdb_stub_resume_cpu(int cpu_id);
59 |
60 | // Called when the GDB stub wants to single-step the specified CPU. The function should not wait
61 | // for the CPU to resume or to halt.
62 | void gdb_stub_step_cpu(int cpu_id);
63 |
64 | // Called when the GDB stub wants to read the PC register on a specific CPU.
65 | uint64_t gdb_stub_cpu_pc(int cpu_id);
66 |
67 | // Called when the GDB stub wants to read the registers on a specific CPU.
68 | void gdb_stub_read_registers(int cpu_id, struct gdb_registers *registers);
69 |
70 | // Called when the GDB stub wants to write the registers on a specific CPU.
71 | void gdb_stub_write_registers(int cpu_id, const struct gdb_registers *registers);
72 |
73 | // Called when the GDB stub wants to read memory from a specific CPU.
74 | size_t gdb_stub_read_memory(int cpu_id, uint64_t address, void *data, size_t length);
75 |
76 | // Called when the GDB stub wants to write memory from a specific CPU.
77 | size_t gdb_stub_write_memory(int cpu_id, uint64_t address, const void *data, size_t length);
78 |
79 | // Called when the GDB stub wants to allocate memory with the specified permissions.
80 | uint64_t gdb_stub_allocate_jit_memory(size_t size, int perm);
81 |
82 | // Called when the GDB stub wants to deallocate memory previously allocated with
83 | // gdb_stub_allocate_jit_memory().
84 | bool gdb_stub_deallocate_jit_memory(uint64_t address);
85 |
86 | // ---- The GDB stub entry points -----------------------------------------------------------------
87 |
88 | // Call this once at the beginning to initialize the GDB stub state.
89 | void gdb_stub_init(uint32_t cpu_mask, uint32_t halted_mask);
90 |
91 | // Call this once to initialize the Mach-O header of the main kernel.
92 | void gdb_stub_set_mach_header(const struct mach_header_64 *mach_header);
93 |
94 | // Call this once to set the number of available hardware watchpoints.
95 | void gdb_stub_set_hardware_watchpoint_count(unsigned hardware_watchpoint_count);
96 |
97 | // Call this when a CPU halts due to a hardware breakpoint. This function simply records the
98 | // breakpoint information in the GDB stub, it does not begin processing the event.
99 | void gdb_stub_hit_hardware_breakpoint(int cpu_id);
100 |
101 | // Call this when a CPU halts due to a hardware watchpoint. This function simply records the
102 | // watchpoint information in the GDB stub, it does not begin processing the event.
103 | void gdb_stub_hit_hardware_watchpoint(int cpu_id, uint64_t address);
104 |
105 | // Call this function when a CPU halts because it completed a single-step operation. This function
106 | // simply records the step information in the GDB stub, it does not begin processing the event.
107 | void gdb_stub_did_step(int cpu_id);
108 |
109 | // Call this function when a CPU halts because it was interrupted. This function simply records the
110 | // halt information in the GDB stub, it does not begin processing the event.
111 | void gdb_stub_did_halt(int cpu_id);
112 |
113 | // Call this when information about all current halts has been recorded with the
114 | // gdb_stub_hit_hardware_breakpoint(), ..., gdb_stub_did_halt() functions and the GDB stub should
115 | // now process that information and act accordingly.
116 | // The halted_mask argument is a mask of the CPUs that are halted. This is a debugging check for
117 | // the GDB stub that it is managing state correctly.
118 | void gdb_stub_process_halts(uint32_t halted_mask);
119 |
120 | // Call this when a packet becomes available over serial.
121 | void gdb_stub_packet(void);
122 |
123 | // This function can be called to log a critical event over serial. It may interfere with the
124 | // normal operation of the debugger, so only do so for debugging critical issues.
125 | void gdb_stub_log(const char *message, ...);
126 |
127 | #endif
128 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/if_value.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef IF_VALUE
21 |
22 | /*
23 | * IF_VALUE(_x_)(_y_)(_z_)
24 | *
25 | * Description:
26 | * If _x_ is not empty, produces _y_, else produces _z_. Do not use or redefine macros
27 | * beginning with _IF_VALUE_.
28 | */
29 |
30 | // _IF_VALUE__SECOND() returns the second argument.
31 | #define _IF_VALUE__SECOND(_a, _b, ...) _b
32 | // _IF_VALUE__SECOND_2() does the same as _IF_VALUE__SECOND() after an additional round of
33 | // parameter expansion.
34 | #define _IF_VALUE__SECOND_2(_a, _b, ...) _IF_VALUE__SECOND(_a, _b, __VA_ARGS__)
35 | // _IF_VALUE__CHECK__IF_VALUE__IS_EMPTY() is used by _IF_VALUE__CHECK to test whether the argument
36 | // is _IF_VALUE__IS_EMPTY and return _IF_VALUE__IS_EMPTY if so.
37 | #define _IF_VALUE__CHECK__IF_VALUE__IS_EMPTY() ~, _IF_VALUE__IS_EMPTY
38 | // _IF_VALUE__CHECK() produces _IF_VALUE__IS_EMPTY if _first is _IF_VALUE__IS_EMPTY and
39 | // _IF_VALUE__NOT_EMPTY otherwise.
40 | #define _IF_VALUE__CHECK(_first, ...) _IF_VALUE__SECOND_2(_IF_VALUE__CHECK_ ## _first (), _IF_VALUE__NOT_EMPTY, ~)
41 | // _IF_VALUE__CHECK_2() does the same as _IF_VALUE__CHECK() after an additional round of parameter
42 | // expansion.
43 | #define _IF_VALUE__CHECK_2(_first, ...) _IF_VALUE__CHECK(_first, __VA_ARGS__)
44 | // _IF_VALUE__IS_EMPTY takes 2 groups of parentheses and returns the unwrapped value of the first
45 | // group.
46 | #define _IF_VALUE__IS_EMPTY(...) _IF_VALUE__IS_EMPTY_1
47 | #define _IF_VALUE__IS_EMPTY_1(...) __VA_ARGS__
48 | // _IF_VALUE__NOT_EMPTY takes 2 groups of parentheses and returns the unwrapped value of the second
49 | // group.
50 | #define _IF_VALUE__NOT_EMPTY(...) __VA_ARGS__ _IF_VALUE__NOT_EMPTY_1
51 | #define _IF_VALUE__NOT_EMPTY_1(...) /* nothing */
52 | // IF_VALUE() produces _IF_VALUE__IS_EMPTY if _maybe_empty is empty and _IF_VALUE__NOT_EMPTY
53 | // otherwise.
54 | #define IF_VALUE(_maybe_empty) _IF_VALUE__CHECK_2(_IF_VALUE__CHECK _maybe_empty (_IF_VALUE__IS_EMPTY, ~), ~)
55 |
56 | #endif
57 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/jit_heap.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #include "jit_heap.h"
21 |
22 | #include "page_table.h"
23 | #include "primitives.h"
24 |
25 | // ---- JIT heap internals ------------------------------------------------------------------------
26 |
27 | #define PAGE_SIZE 0x4000
28 |
29 | #define JIT_HEAP_PAGES (JIT_HEAP_SIZE / PAGE_SIZE)
30 |
31 | // The JIT heap. Since we will be setting permissions on individual allocations, the allocation
32 | // granularity is a single page. This means that the jit heap itself must be page-aligned.
33 | static uint8_t *jit_heap;
34 |
35 | _Static_assert(JIT_HEAP_PAGES < (1uL << (sizeof(uint8_t) * 8)),
36 | "struct jit_heap_page: The number of JIT heap pages must fit in a uint8_t");
37 |
38 | // For each page in the JIT heap, we have a small structure describing the allocation to which that
39 | // page belongs.
40 | struct jit_heap_page {
41 | // The index of the first page of this allocation.
42 | uint8_t alloc_index;
43 | // The number of allocated pages in this allocation.
44 | uint8_t alloc_count;
45 | // The VM permissions of the page (rwx).
46 | uint8_t vm_permissions;
47 | };
48 |
49 | // The information for each heap page.
50 | static struct jit_heap_page jit_heap_pages[JIT_HEAP_PAGES] = {};
51 |
52 | // Verifies that the specified address is part of the JIT heap.
53 | static bool
54 | verify_jit_heap_address(void *address) {
55 | uint8_t *p = address;
56 | return (jit_heap <= p && p < jit_heap + JIT_HEAP_SIZE);
57 | }
58 |
59 | // Set the alloc_index and alloc_count fields of the pages in the allocation.
60 | static void
61 | claim_jit_heap_allocation(size_t alloc_index, size_t alloc_count) {
62 | struct jit_heap_page *page = &jit_heap_pages[alloc_index];
63 | for (size_t i = 0; i < alloc_count; i++) {
64 | page->alloc_index = alloc_index;
65 | page->alloc_count = alloc_count;
66 | page++;
67 | }
68 | }
69 |
70 | // Find a region in the heap large enough for the specified allocation. The jit_heap_page structs
71 | // for all pages in the allocation have the alloc_index and alloc_count fields initialized. The
72 | // jit_heap_page struct for the first page is returned.
73 | struct jit_heap_page *
74 | reserve_jit_heap_allocation(size_t page_count) {
75 | // Find a stretch of unallocated pages of the requisite size.
76 | size_t alloc_index = 0;
77 | size_t alloc_count = 0;
78 | for (size_t page_index = 0; page_index < JIT_HEAP_PAGES; page_index++) {
79 | if (jit_heap_pages[page_index].alloc_count == 0) {
80 | // This one is free. Bump the alloc_count.
81 | if (alloc_count == 0) {
82 | alloc_index = page_index;
83 | }
84 | alloc_count++;
85 | if (alloc_count >= page_count) {
86 | claim_jit_heap_allocation(alloc_index, alloc_count);
87 | return &jit_heap_pages[alloc_index];
88 | }
89 | } else {
90 | // This one is allocated. Reset our count.
91 | alloc_count = 0;
92 | }
93 | }
94 | return NULL;
95 | }
96 |
97 | // Get the address of the start of the allocation containing this page.
98 | static void *
99 | jit_heap_allocation_address(size_t alloc_index) {
100 | return &jit_heap[alloc_index * PAGE_SIZE];
101 | }
102 |
103 | // Find the JIT heap allocation starting at this address.
104 | struct jit_heap_page *
105 | find_jit_heap_allocation(void *address) {
106 | if (!verify_jit_heap_address(address)) {
107 | return NULL;
108 | }
109 | if ((((uintptr_t) address) & (PAGE_SIZE - 1)) != 0) {
110 | return NULL;
111 | }
112 | size_t page_index = ((uint8_t *) address - jit_heap) / PAGE_SIZE;
113 | struct jit_heap_page *page = &jit_heap_pages[page_index];
114 | if (page->alloc_index != page_index) {
115 | return NULL;
116 | }
117 | if (page->alloc_count == 0) {
118 | return NULL;
119 | }
120 | return page;
121 | }
122 |
123 | static void
124 | clear_jit_heap_page(struct jit_heap_page *page) {
125 | page->alloc_index = 0;
126 | page->alloc_count = 0;
127 | page->vm_permissions = 0;
128 | }
129 |
130 | static void
131 | clear_jit_heap_allocation(struct jit_heap_page *page) {
132 | size_t alloc_index = page->alloc_index;
133 | size_t alloc_count = page->alloc_count;
134 | bzero(&jit_heap[alloc_index], alloc_count * PAGE_SIZE);
135 | for (size_t i = 0; i < alloc_count; i++) {
136 | clear_jit_heap_page(page);
137 | page++;
138 | }
139 | }
140 |
141 | // ---- JIT heap API ------------------------------------------------------------------------------
142 |
143 | void
144 | jit_heap_init(void *heap) {
145 | jit_heap = heap;
146 | jit_heap_reset();
147 | }
148 |
149 | void
150 | jit_heap_reset() {
151 | for (size_t i = 0; i < JIT_HEAP_PAGES; i++) {
152 | clear_jit_heap_page(&jit_heap_pages[i]);
153 | }
154 | }
155 |
156 | void *
157 | jit_heap_allocate(size_t size, int vm_prot) {
158 | size_t page_count = (size + PAGE_SIZE - 1) / PAGE_SIZE;
159 | struct jit_heap_page *page = reserve_jit_heap_allocation(page_count);
160 | if (page == NULL) {
161 | return NULL;
162 | }
163 | size_t alloc_index = page->alloc_index;
164 | size_t alloc_count = page->alloc_count;
165 | page_table_sync();
166 | for (size_t i = 0; i < alloc_count; i++) {
167 | void *heap_page = jit_heap_allocation_address(alloc_index + i);
168 | // We'll set the page for maximum permissions, regardless of what the user asked
169 | // for.
170 | ttbr1_page_table_set_page_attributes(heap_page, 1, 0, SH_OUTER, AP_RWNA,
171 | ATTR_Normal_WriteBack);
172 | }
173 | page_table_sync();
174 | return jit_heap_allocation_address(alloc_index);
175 | }
176 |
177 | bool
178 | jit_heap_deallocate(void *address) {
179 | struct jit_heap_page *page = find_jit_heap_allocation(address);
180 | if (page == NULL) {
181 | return false;
182 | }
183 | clear_jit_heap_allocation(page);
184 | return true;
185 | }
186 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/jit_heap.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef JIT_HEAP__H_
21 | #define JIT_HEAP__H_
22 |
23 | #include
24 | #include
25 | #include
26 |
27 | // The size of the JIT heap.
28 | #define JIT_HEAP_SIZE (64 * 0x4000)
29 |
30 | /*
31 | * jit_heap_init
32 | *
33 | * Description:
34 | * Initialize the JIT heap to use the specified allocation.
35 | */
36 | void jit_heap_init(void *heap);
37 |
38 | /*
39 | * jit_heap_reset
40 | *
41 | * Description:
42 | * Reset the JIT heap, freeing all outstanding allocations.
43 | */
44 | void jit_heap_reset(void);
45 |
46 | /*
47 | * jit_heap_allocate
48 | *
49 | * Description:
50 | * Allocate memory from the JIT heap with the specified permissions.
51 | */
52 | void *jit_heap_allocate(size_t size, int vm_prot);
53 |
54 | /*
55 | * jit_heap_deallocate
56 | *
57 | * Description:
58 | * Deallocate the specified JIT heap allocation.
59 | */
60 | bool jit_heap_deallocate(void *address);
61 |
62 | #endif
63 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/kernel_extern.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef KERNEL_EXTERN__H_
21 | #define KERNEL_EXTERN__H_
22 |
23 | // Declare any kernel variables as KERNEL_EXTERN and include the static addresses in the symbols
24 | // files.
25 | #define KERNEL_EXTERN extern __attribute__((weak_import))
26 |
27 | #endif
28 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/page_table.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef PAGE_TABLE__H_
21 | #define PAGE_TABLE__H_
22 |
23 | #include
24 | #include
25 | #include
26 |
27 | // ---- Kernel virtual to physical translation ----------------------------------------------------
28 |
29 | /*
30 | * kernel_virtual_to_physical
31 | *
32 | * Description:
33 | * Translate the specified kernel virtual address into the corresponding physical address. The
34 | * kernel's shared TTBR1_EL1 is used for translation.
35 | */
36 | uint64_t kernel_virtual_to_physical(uint64_t kvaddr);
37 |
38 | // ---- Cacheing ----------------------------------------------------------------------------------
39 |
40 | /*
41 | * cache_invalidate
42 | *
43 | * Description:
44 | * Invalidate cache lines for the specified virtual address range.
45 | */
46 | void cache_invalidate(void *address, size_t size);
47 |
48 | /*
49 | * cache_clean_and_invalidate
50 | *
51 | * Description:
52 | * Clean and invalidate cache lines for the specified virtual address range.
53 | */
54 | void cache_clean_and_invalidate(void *address, size_t size);
55 |
56 | // ---- Memory mapping via TTBR0_EL1 --------------------------------------------------------------
57 |
58 | /*
59 | * ttbr0_page_tables_init
60 | *
61 | * Description:
62 | * Set up TTBR0_EL1 for mapping physical memory. This mapping is only present on this CPU
63 | * core, and thus will not be accessible to the rest of the kernel.
64 | *
65 | * This function should only be called once this thread has been pinned to the CPU, since if
66 | * we move to another CPU core then the TTBR0_EL1 register will no longer point to our page
67 | * tables.
68 | */
69 | void ttbr0_page_tables_init(void);
70 |
71 | #define SH_NONE 0x0
72 | #define SH_OUTER 0x2
73 | #define SH_INNER 0x3
74 |
75 | #define AP_RWNA 0x0
76 | #define AP_RWRW 0x1
77 | #define AP_RONA 0x2
78 | #define AP_RORO 0x3
79 |
80 | #define ATTR_Normal_WriteBack 0
81 | #define ATTR_Normal_NonCacheable 1
82 | #define ATTR_Normal_WriteThrough 2
83 | #define ATTR_Device_nGnRnE 3
84 | #define ATTR_Device_nGnRE 5
85 |
86 | /*
87 | * ttbr0_map
88 | *
89 | * Description:
90 | * Map the specified physical address range. The page is mapped for all access and with the
91 | * specified attributes.
92 | *
93 | * Due to how the mapping is implemented, a maximum of 4095 pages can be mapped
94 | * simultaneously.
95 | */
96 | void *ttbr0_map(uint64_t paddr, size_t size, unsigned attr);
97 |
98 | /*
99 | * ttbr0_map_io
100 | *
101 | * Description:
102 | * A convenience wrapper around ttbr0_map() for mapping device memory suitable for MMIO.
103 | */
104 | static inline void *
105 | ttbr0_map_io(uint64_t paddr, size_t size) {
106 | return ttbr0_map(paddr, size, ATTR_Device_nGnRnE);
107 | }
108 |
109 | /*
110 | * ttbr0_unmap
111 | *
112 | * Description:
113 | * Unmap a mapping established via ttbr0_map().
114 | */
115 | void ttbr0_unmap(void *address, size_t size);
116 |
117 | // ---- Accessing physical memory -----------------------------------------------------------------
118 |
119 | /*
120 | * physical_read_64
121 | *
122 | * Description:
123 | * Read a 64-bit value from physical memory.
124 | */
125 | uint64_t physical_read_64(uint64_t paddr);
126 |
127 | /*
128 | * physical_write_64
129 | *
130 | * Description:
131 | * Write a 64-bit value to physical memory.
132 | */
133 | void physical_write_64(uint64_t paddr, uint64_t value);
134 |
135 | // ---- Modifying page tables ---------------------------------------------------------------------
136 |
137 | /*
138 | * ttbr1_page_table_set_page_attributes
139 | *
140 | * Description:
141 | * Set attributes on the TTBR1_EL1 translation table entry mapping the specified page.
142 | */
143 | bool ttbr1_page_table_set_page_attributes(void *page,
144 | unsigned uxn, unsigned pxn, unsigned sh, unsigned ap, unsigned attr);
145 |
146 | /*
147 | * ttbr1_page_table_swap_physical_page
148 | *
149 | * Description:
150 | * Modify the TTBR1_EL1 page tables so that all virtual mappings of the specified physical
151 | * page instead refer to another physical page.
152 | */
153 | size_t ttbr1_page_table_swap_physical_page(uint64_t paddr_old, uint64_t paddr_new);
154 |
155 | /*
156 | * page_table_sync()
157 | *
158 | * Description:
159 | * Ensure that changes to the page table become visible.
160 | */
161 | void page_table_sync(void);
162 |
163 | #endif
164 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/primitives.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 |
21 | #include
22 | #include
23 |
24 | // These functions and globals are used in compiler-generated code. We'd prefer not to use the
25 | // kernel's versions, since calling kernel functions and reading kernel variables could interfere
26 | // with the operation of the debugger. (When using per-core hardware breakpoints and watchpoints
27 | // this will obviously be fine, but it could be problematic if the debugger rewrites kernel
28 | // memory.)
29 |
30 | uint64_t __stack_chk_guard = 0x1122334455667788;
31 |
32 | void
33 | __stack_chk_fail() {
34 | for (;;) {}
35 | }
36 |
37 | void
38 | bzero(void *s, size_t n) {
39 | uint8_t *p = s;
40 | for (size_t i = 0; i < n; i++) {
41 | p[i] = 0;
42 | }
43 | }
44 |
45 | // These functions are not necessarily used automatically by the compiler but they are useful to
46 | // have.
47 |
48 | void
49 | memcpy(void *restrict dst, const void *restrict src, size_t n) {
50 | for (size_t i = 0; i < n; i++) {
51 | ((uint8_t *)dst)[i] = ((uint8_t *)src)[i];
52 | }
53 | }
54 |
55 | void
56 | memmove(void *dst, const void *src, size_t n) {
57 | uint8_t *d = dst;
58 | const uint8_t *s = src;
59 | if (d < s) {
60 | for (size_t i = 0; i < n; i++) {
61 | d[i] = s[i];
62 | }
63 | } else if (s < d) {
64 | size_t i = n;
65 | while (i > 0) {
66 | i--;
67 | d[i] = s[i];
68 | }
69 | }
70 | }
71 |
72 | size_t
73 | strlen(const char *str) {
74 | const char *end = str;
75 | for (;;) {
76 | if (*end == 0) {
77 | return (end - str);
78 | }
79 | end++;
80 | }
81 | }
82 |
83 | int
84 | strcmp(const char *s1, const char *s2) {
85 | for (;;) {
86 | unsigned char c1 = (unsigned char) *s1;
87 | unsigned char c2 = (unsigned char) *s2;
88 | int diff = c1 - c2;
89 | if (diff != 0) {
90 | return diff;
91 | }
92 | if (c1 == 0) {
93 | return 0;
94 | }
95 | s1++;
96 | s2++;
97 | }
98 | }
99 |
100 | int
101 | strncmp(const char *s1, const char *s2, size_t n) {
102 | while (n > 0) {
103 | unsigned char c1 = (unsigned char) *s1;
104 | unsigned char c2 = (unsigned char) *s2;
105 | int diff = c1 - c2;
106 | if (diff != 0) {
107 | return diff;
108 | }
109 | if (c1 == 0) {
110 | return 0;
111 | }
112 | s1++;
113 | s2++;
114 | n--;
115 | }
116 | return 0;
117 | }
118 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/primitives.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef PRIMITIVES__H_
21 | #define PRIMITIVES__H_
22 |
23 | #include
24 |
25 | void bzero(void *s, size_t n);
26 |
27 | void memcpy(void *restrict dst, const void *restrict src, size_t n);
28 |
29 | void memmove(void *dst, const void *src, size_t n);
30 |
31 | int strcmp(const char *s1, const char *s2);
32 |
33 | size_t strlen(const char *str);
34 |
35 | int strncmp(const char *s1, const char *s2, size_t n);
36 |
37 | #endif
38 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/third_party/boot_args.h:
--------------------------------------------------------------------------------
1 | // This file is from XNU-4903.221.2, pexpert/pexpert/arm64/boot.h, available at
2 | // https://opensource.apple.com/tarballs/xnu/xnu-4903.221.2.tar.gz. It has been modified for
3 | // inclusion in this project.
4 | /*
5 | * Copyright (c) 2007-2009 Apple Inc. All rights reserved.
6 | * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
7 | */
8 | /*
9 | * @OSF_COPYRIGHT@
10 | */
11 |
12 | #ifndef _PEXPERT_ARM64_BOOT_H_
13 | #define _PEXPERT_ARM64_BOOT_H_
14 |
15 | #define BOOT_LINE_LENGTH 256
16 |
17 | /*
18 | * Video information..
19 | */
20 |
21 | struct Boot_Video {
22 | unsigned long v_baseAddr; /* Base address of video memory */
23 | unsigned long v_display; /* Display Code (if Applicable */
24 | unsigned long v_rowBytes; /* Number of bytes per pixel row */
25 | unsigned long v_width; /* Width */
26 | unsigned long v_height; /* Height */
27 | unsigned long v_depth; /* Pixel Depth and other parameters */
28 | };
29 |
30 | typedef struct Boot_Video Boot_Video;
31 |
32 | /* Boot argument structure - passed into Mach kernel at boot time.
33 | */
34 | #define kBootArgsRevision 1
35 | #define kBootArgsRevision2 2 /* added boot_args.bootFlags */
36 | #define kBootArgsVersion1 1
37 | #define kBootArgsVersion2 2
38 |
39 | typedef struct boot_args {
40 | uint16_t Revision; /* Revision of boot_args structure */
41 | uint16_t Version; /* Version of boot_args structure */
42 | uint64_t virtBase; /* Virtual base of memory */
43 | uint64_t physBase; /* Physical base of memory */
44 | uint64_t memSize; /* Size of memory */
45 | uint64_t topOfKernelData; /* Highest physical address used in kernel data area */
46 | Boot_Video Video; /* Video Information */
47 | uint32_t machineType; /* Machine Type */
48 | void *deviceTreeP; /* Base of flattened device tree */
49 | uint32_t deviceTreeLength; /* Length of flattened tree */
50 | char CommandLine[BOOT_LINE_LENGTH]; /* Passed in command line */
51 | uint64_t bootFlags; /* Additional flags specified by the bootloader */
52 | uint64_t memSizeActual; /* Actual size of memory */
53 | } boot_args;
54 |
55 | #endif /* _PEXPERT_ARM64_BOOT_H_ */
56 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/third_party/kmod.h:
--------------------------------------------------------------------------------
1 | // This file is from Xcode 11.2.1 (11B500), at the path
2 | // Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/mach/kmod.h.
3 | // It has been modified for inclusion in this project.
4 | /*
5 | * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
6 | *
7 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
8 | *
9 | * This file contains Original Code and/or Modifications of Original Code
10 | * as defined in and that are subject to the Apple Public Source License
11 | * Version 2.0 (the 'License'). You may not use this file except in
12 | * compliance with the License. The rights granted to you under the License
13 | * may not be used to create, or enable the creation or redistribution of,
14 | * unlawful or unlicensed copies of an Apple operating system, or to
15 | * circumvent, violate, or enable the circumvention or violation of, any
16 | * terms of an Apple operating system software license agreement.
17 | *
18 | * Please obtain a copy of the License at
19 | * http://www.opensource.apple.com/apsl/ and read it before using this file.
20 | *
21 | * The Original Code and all software distributed under the License are
22 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
23 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
24 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
25 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
26 | * Please see the License for the specific language governing rights and
27 | * limitations under the License.
28 | *
29 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
30 | */
31 | /*
32 | * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
33 | * support for mandatory and extensible security protections. This notice
34 | * is included in support of clause 2.2 (b) of the Apple Public License,
35 | * Version 2.0.
36 | */
37 |
38 | #ifndef _MACH_KMOD_H_
39 | #define _MACH_KMOD_H_
40 |
41 | #include
42 |
43 | #if PRAGMA_MARK
44 | #pragma mark Basic macros & typedefs
45 | #endif
46 | /***********************************************************************
47 | * Basic macros & typedefs
48 | ***********************************************************************/
49 | #define KMOD_MAX_NAME 64
50 |
51 | struct kmod_info;
52 | typedef int kmod_start_func_t(struct kmod_info * ki, void * data);
53 | typedef int kmod_stop_func_t(struct kmod_info * ki, void * data);
54 |
55 | #if PRAGMA_MARK
56 | #pragma mark Structure definitions
57 | #endif
58 | /***********************************************************************
59 | * Structure definitions
60 | *
61 | * All structures must be #pragma pack(4).
62 | ***********************************************************************/
63 | #pragma pack(push, 4)
64 |
65 | /* Run-time struct only; never saved to a file */
66 | typedef struct kmod_reference {
67 | struct kmod_reference * next;
68 | struct kmod_info * info;
69 | } kmod_reference_t;
70 |
71 | /***********************************************************************
72 | * Warning: Any changes to the kmod_info structure affect the
73 | * KMOD_..._DECL macros below.
74 | ***********************************************************************/
75 |
76 | /* The kmod_info_t structure is only safe to use inside the running
77 | * kernel. If you need to work with a kmod_info_t structure outside
78 | * the kernel, please use the compatibility definitions below.
79 | */
80 | typedef struct kmod_info {
81 | struct kmod_info * next;
82 | int32_t info_version; // version of this structure
83 | uint32_t id;
84 | char name[KMOD_MAX_NAME];
85 | char version[KMOD_MAX_NAME];
86 | int32_t reference_count; // # linkage refs to this
87 | kmod_reference_t * reference_list; // who this refs (links on)
88 | uint64_t address; // starting address
89 | uint64_t size; // total size
90 | uint64_t hdr_size; // unwired hdr size
91 | kmod_start_func_t * start;
92 | kmod_stop_func_t * stop;
93 | } kmod_info_t;
94 |
95 | /* A compatibility definition of kmod_info_t for 32-bit kexts.
96 | */
97 | typedef struct kmod_info_32_v1 {
98 | uint32_t next_addr;
99 | int32_t info_version;
100 | uint32_t id;
101 | uint8_t name[KMOD_MAX_NAME];
102 | uint8_t version[KMOD_MAX_NAME];
103 | int32_t reference_count;
104 | uint32_t reference_list_addr;
105 | uint32_t address;
106 | uint32_t size;
107 | uint32_t hdr_size;
108 | uint32_t start_addr;
109 | uint32_t stop_addr;
110 | } kmod_info_32_v1_t;
111 |
112 | /* A compatibility definition of kmod_info_t for 64-bit kexts.
113 | */
114 | typedef struct kmod_info_64_v1 {
115 | uint64_t next_addr;
116 | int32_t info_version;
117 | uint32_t id;
118 | uint8_t name[KMOD_MAX_NAME];
119 | uint8_t version[KMOD_MAX_NAME];
120 | int32_t reference_count;
121 | uint64_t reference_list_addr;
122 | uint64_t address;
123 | uint64_t size;
124 | uint64_t hdr_size;
125 | uint64_t start_addr;
126 | uint64_t stop_addr;
127 | } kmod_info_64_v1_t;
128 |
129 | #pragma pack(pop)
130 |
131 | #if PRAGMA_MARK
132 | #pragma mark Kmod structure declaration macros
133 | #endif
134 | /***********************************************************************
135 | * Kmod structure declaration macros
136 | ***********************************************************************/
137 | #define KMOD_INFO_NAME kmod_info
138 | #define KMOD_INFO_VERSION 1
139 |
140 | #define KMOD_DECL(name, version) \
141 | static kmod_start_func_t name ## _module_start; \
142 | static kmod_stop_func_t name ## _module_stop; \
143 | kmod_info_t KMOD_INFO_NAME = { 0, KMOD_INFO_VERSION, -1U, \
144 | { #name }, { version }, -1, 0, 0, 0, 0, \
145 | name ## _module_start, \
146 | name ## _module_stop };
147 |
148 | #define KMOD_EXPLICIT_DECL(name, version, start, stop) \
149 | kmod_info_t KMOD_INFO_NAME = { 0, KMOD_INFO_VERSION, -1U, \
150 | { #name }, { version }, -1, 0, 0, 0, 0, \
151 | start, stop };
152 |
153 | #endif /* _MACH_KMOD_H_ */
154 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/usb/synopsys_otg_regs.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef SYNOPSYS_OTG_REGS__H_
21 | #define SYNOPSYS_OTG_REGS__H_
22 |
23 | #ifndef SYNOPSYS_OTG_REGISTER
24 | #define SYNOPSYS_OTG_REGISTER(_x) (_x)
25 | #endif
26 |
27 | #define rGOTGCTL (SYNOPSYS_OTG_REGISTER(0x000))
28 | #define rGOTGINT (SYNOPSYS_OTG_REGISTER(0x004))
29 | #define rGAHBCFG (SYNOPSYS_OTG_REGISTER(0x008))
30 | #define rGUSBCFG (SYNOPSYS_OTG_REGISTER(0x00c))
31 | #define rGRSTCTL (SYNOPSYS_OTG_REGISTER(0x010))
32 | #define rGINTSTS (SYNOPSYS_OTG_REGISTER(0x014))
33 | #define rGINTMSK (SYNOPSYS_OTG_REGISTER(0x018))
34 | #define rGRXSTSR (SYNOPSYS_OTG_REGISTER(0x01c))
35 | #define rGRXSTSP (SYNOPSYS_OTG_REGISTER(0x020))
36 | #define rGRXFSIZ (SYNOPSYS_OTG_REGISTER(0x024))
37 | #define rGNPTXFSIZ (SYNOPSYS_OTG_REGISTER(0x028))
38 | #define rGNPTXSTS (SYNOPSYS_OTG_REGISTER(0x02c))
39 | #define rGI2CCTL (SYNOPSYS_OTG_REGISTER(0x030))
40 | #define rGPVNDCTL (SYNOPSYS_OTG_REGISTER(0x034))
41 | #define rGGPIO (SYNOPSYS_OTG_REGISTER(0x038))
42 | #define rGUID (SYNOPSYS_OTG_REGISTER(0x03c))
43 | #define rGSNPSID (SYNOPSYS_OTG_REGISTER(0x040))
44 | #define rGHWCFG1 (SYNOPSYS_OTG_REGISTER(0x044))
45 | #define rGHWCFG2 (SYNOPSYS_OTG_REGISTER(0x048))
46 | #define rGHWCFG3 (SYNOPSYS_OTG_REGISTER(0x04c))
47 | #define rGHWCFG4 (SYNOPSYS_OTG_REGISTER(0x050))
48 | #define rGLPMCFG (SYNOPSYS_OTG_REGISTER(0x054))
49 | #define rGPWRDN (SYNOPSYS_OTG_REGISTER(0x058))
50 | #define rGDFIFOCFG (SYNOPSYS_OTG_REGISTER(0x05c))
51 | #define rADPCTL (SYNOPSYS_OTG_REGISTER(0x060))
52 |
53 | #define rHPTXFSIZ (SYNOPSYS_OTG_REGISTER(0x100))
54 | #define rDTXFSIZ(n) (SYNOPSYS_OTG_REGISTER(0x104 + 0x4 * (n - 1)))
55 |
56 | #define rHPTXSIZ (SYNOPSYS_OTG_REGISTER(0x400))
57 |
58 | #define rHPRT0 (SYNOPSYS_OTG_REGISTER(0x440))
59 |
60 | #define rDCFG (SYNOPSYS_OTG_REGISTER(0x800))
61 | #define rDCTL (SYNOPSYS_OTG_REGISTER(0x804))
62 | #define rDSTS (SYNOPSYS_OTG_REGISTER(0x808))
63 | #define rDIEPMSK (SYNOPSYS_OTG_REGISTER(0x810))
64 | #define rDOEPMSK (SYNOPSYS_OTG_REGISTER(0x814))
65 | #define rDAINT (SYNOPSYS_OTG_REGISTER(0x818))
66 | #define rDAINTMSK (SYNOPSYS_OTG_REGISTER(0x81c))
67 |
68 | #define rDIEPCTL(ep) (SYNOPSYS_OTG_REGISTER(0x900 + 0x20 * ep))
69 | #define rDIEPINT(ep) (SYNOPSYS_OTG_REGISTER(0x908 + 0x20 * ep))
70 | #define rDIEPTSIZ(ep) (SYNOPSYS_OTG_REGISTER(0x910 + 0x20 * ep))
71 | #define rDIEPDMA(ep) (SYNOPSYS_OTG_REGISTER(0x914 + 0x20 * ep))
72 | #define rDTXFSTS(ep) (SYNOPSYS_OTG_REGISTER(0x918 + 0x20 * ep))
73 | #define rDIEPDMAB(ep) (SYNOPSYS_OTG_REGISTER(0x91c + 0x20 * ep))
74 |
75 | #define rDOEPCTL(ep) (SYNOPSYS_OTG_REGISTER(0xb00 + 0x20 * ep))
76 | #define rDOEPINT(ep) (SYNOPSYS_OTG_REGISTER(0xb08 + 0x20 * ep))
77 | #define rDOEPTSIZ(ep) (SYNOPSYS_OTG_REGISTER(0xb10 + 0x20 * ep))
78 | #define rDOEPDMA(ep) (SYNOPSYS_OTG_REGISTER(0xb14 + 0x20 * ep))
79 | #define rDOEPDMAB(ep) (SYNOPSYS_OTG_REGISTER(0xb1c + 0x20 * ep))
80 |
81 | #endif
82 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/usb/usb.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef USB__H_
21 | #define USB__H_
22 |
23 | #include
24 | #include
25 |
26 | // The amount of memory needed for the USB stack.
27 | #define USB_STACK_MEMORY_SIZE 0x4000
28 |
29 | /*
30 | * usb_init
31 | *
32 | * Description:
33 | * Initialize state for the USB stack. This does not interact with the USB hardware so it may
34 | * be called before preemption is disabled.
35 | *
36 | * dma should be a pointer to a page with a low physical address suitable for use by the USB
37 | * controller's DMA engine.
38 | *
39 | * memory should be a pointer to a page-aligned allocation of size USB_STACK_MEMORY_SIZE for
40 | * internal use by the USB stack.
41 | */
42 | void usb_init(void *dma, void *memory);
43 |
44 | /*
45 | * usb_start
46 | *
47 | * Description:
48 | * Start the USB stack for communication with the host.
49 | *
50 | * This should only be called once the system is stopped and with interrupts disabled.
51 | */
52 | void usb_start(void);
53 |
54 | /*
55 | * usb_process
56 | *
57 | * Description:
58 | * Perform a single round of USB processing. This should be called after usb_read() and
59 | * usb_write(), and at every USB interrupt. A simple implementation would be to call this
60 | * function on every iteration of the debugger main loop.
61 | */
62 | void usb_process(void);
63 |
64 | /*
65 | * usb_read
66 | *
67 | * Description:
68 | * Read data sent over USB.
69 | *
70 | * Up to 0x1000 bytes of data will be buffered.
71 | */
72 | size_t usb_read(void *buffer, size_t size);
73 |
74 | /*
75 | * usb_write
76 | *
77 | * Description:
78 | * Write data out over USB. No actual data is sent until a call to usb_write_commit().
79 | *
80 | * The maximum packet size is 0x1000. However, it is possible that less than 0x1000 bytes can
81 | * be written if the buffer is already partially full from the last write.
82 | */
83 | size_t usb_write(const void *buffer, size_t size);
84 |
85 | /*
86 | * usb_write_commit
87 | *
88 | * Description:
89 | * Send any data written via usb_write() over USB to the host.
90 | */
91 | void usb_write_commit(void);
92 |
93 | // ---- Transfer API ------------------------------------------------------------------------------
94 |
95 | /*
96 | * usb_in_transfer
97 | *
98 | * Description:
99 | * Perform an IN transfer on the specified endpoint.
100 | *
101 | * The data buffer must remain alive until the completion callback is invoked.
102 | */
103 | void usb_in_transfer(uint8_t ep_addr, const void *data, uint32_t size, void (*callback)(void));
104 |
105 | /*
106 | * usb_out_transfer
107 | *
108 | * Description:
109 | * Perform an OUT transfer on the specified endpoint.
110 | */
111 | void usb_out_transfer(uint8_t ep_addr, void *data, uint32_t size,
112 | void (*callback)(void *data, uint32_t size, uint32_t transferred));
113 |
114 | /*
115 | * usb_out_transfer_dma
116 | *
117 | * Description:
118 | * Perform an OUT transfer on the specified endpoint, optimized for when the data buffer is
119 | * suitable for DMA.
120 | */
121 | void usb_out_transfer_dma(uint8_t ep_addr, void *data, uint32_t dma, uint32_t size,
122 | void (*callback)(void *data, uint32_t size, uint32_t transferred));
123 |
124 | #endif
125 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/watchdog.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #include "watchdog.h"
21 |
22 | #include "page_table.h"
23 |
24 | // ---- WatchDog Timer ----------------------------------------------------------------------------
25 |
26 | uint64_t watchdog_timer_register_base = 0x2352b0000;
27 |
28 | // The memory-mapped WatchDog Timer registers.
29 | static uint64_t watchdog_registers;
30 |
31 | // Map the WatchDog Timer registers.
32 | static void
33 | map_watchdog_registers() {
34 | if (watchdog_registers == 0) {
35 | watchdog_registers = (uint64_t) ttbr0_map_io(watchdog_timer_register_base, 0x1000);
36 | }
37 | }
38 |
39 | void
40 | disable_watchdog_timer() {
41 | map_watchdog_registers();
42 | *(volatile uint32_t *)(watchdog_registers + 0x0c) = 0;
43 | *(volatile uint32_t *)(watchdog_registers + 0x1c) = 0;
44 | }
45 |
--------------------------------------------------------------------------------
/ktrw_gdb_stub/source/watchdog.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef WATCHDOG__H_
21 | #define WATCHDOG__H_
22 |
23 | #include
24 |
25 | // The physical address of the WatchDog Timer registers. This should be initialized prior to
26 | // calling disable_watchdog_timer().
27 | extern uint64_t watchdog_timer_register_base;
28 |
29 | /*
30 | * disable_watchdog_timer
31 | *
32 | * Description:
33 | * Disables the WatchDog Timer.
34 | */
35 | void disable_watchdog_timer(void);
36 |
37 | #endif
38 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/Makefile:
--------------------------------------------------------------------------------
1 | TARGET = ktrw_kext_loader
2 |
3 | ARCH = arm64
4 | SDK = iphoneos
5 | DEBUG = 0
6 |
7 | SYSROOT := $(shell xcrun --sdk $(SDK) --show-sdk-path)
8 | ifeq ($(SYSROOT),)
9 | $(error Could not find SDK $(SDK))
10 | endif
11 | CLANG := $(shell xcrun --sdk $(SDK) --find clang)
12 | CC := $(CLANG) -isysroot $(SYSROOT) -arch $(ARCH)
13 |
14 | CFLAGS = -Iheaders -Ikernel -Ikernel_call -Ikernel_patches -Ikext_load -Iktrr -Isystem
15 | CFLAGS += -O2
16 | CFLAGS += -Wall -Werror -Wpedantic -Wno-gnu -Wno-language-extension-token
17 | CFLAGS += -Wno-keyword-macro
18 |
19 | ifneq ($(DEBUG),0)
20 | CFLAGS += -DDEBUG=$(DEBUG)
21 | endif
22 |
23 | LDFLAGS = -framework CoreFoundation -framework IOKit
24 |
25 | SOURCES = kernel/kernel_memory.c \
26 | kernel/kernel_parameters.c \
27 | kernel/kernel_slide.c \
28 | kernel/kernel_tasks.c \
29 | kernel_call/kernel_call.c \
30 | kernel_call/kernel_call_7_a11.c \
31 | kernel_call/kernel_call_parameters.c \
32 | kernel_patches/kernel_patches.c \
33 | kext_load/kext_load.c \
34 | kext_load/resolve_symbol.c \
35 | ktrr/ktrr_bypass.c \
36 | ktrr/ktrr_bypass_parameters.c \
37 | system/log.c \
38 | system/map_file.c \
39 | system/platform.c \
40 | system/platform_match.c \
41 | main.c
42 |
43 | HEADERS = headers/IOKitLib.h \
44 | headers/mach_vm.h \
45 | kernel/kernel_memory.h \
46 | kernel/kernel_parameters.h \
47 | kernel/kernel_slide.h \
48 | kernel/kernel_tasks.h \
49 | kernel_call/kernel_call.h \
50 | kernel_call/kernel_call_7_a11.h \
51 | kernel_call/kernel_call_parameters.h \
52 | kernel_patches/kernel_patches.h \
53 | kext_load/kext_load.h \
54 | kext_load/resolve_symbol.h \
55 | ktrr/ktrr_bypass.h \
56 | ktrr/ktrr_bypass_parameters.h \
57 | system/log.h \
58 | system/map_file.h \
59 | system/parameters.h \
60 | system/platform.h \
61 | system/platform_match.h
62 |
63 | $(TARGET): $(SOURCES) $(HEADERS)
64 | $(CC) $(CFLAGS) $(DEFINES) $(LDFLAGS) -o $@ $(SOURCES)
65 |
66 | clean:
67 | rm -f -- $(TARGET)
68 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/app/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #import
21 |
22 | @interface AppDelegate : UIResponder
23 |
24 | @property (strong, nonatomic) UIWindow *window;
25 |
26 |
27 | @end
28 |
29 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/app/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #import "AppDelegate.h"
21 |
22 | #import "bundle_path.h"
23 | #import "kernel_call.h"
24 | #import "kernel_memory.h"
25 | #import "kernel_patches.h"
26 | #import "kext_load.h"
27 | #import "ktrr_bypass.h"
28 | #import "log.h"
29 |
30 |
31 | @interface AppDelegate ()
32 |
33 | @end
34 |
35 | @implementation AppDelegate
36 |
37 |
38 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
39 | // Get the bundle path.
40 | char bundle_path[1024];
41 | get_bundle_path(bundle_path, sizeof(bundle_path));
42 | // Load the kernel symbol database.
43 | char kernel_symbol_database[1024];
44 | snprintf(kernel_symbol_database, sizeof(kernel_symbol_database), "%s/%s", bundle_path,
45 | "kernel_symbols");
46 | bool ok = kext_load_set_kernel_symbol_database(kernel_symbol_database);
47 | if (!ok) {
48 | ERROR("Could not load kernel symbol database");
49 | goto done_0;
50 | }
51 | // Try to get the kernel task port using task_for_pid(). If this works, then KTRR has
52 | // already been bypassed and the kext has already been loaded.
53 | kernel_task_port = MACH_PORT_NULL;
54 | task_for_pid(mach_task_self(), 0, &kernel_task_port);
55 | if (kernel_task_port != MACH_PORT_NULL) {
56 | INFO("task_for_pid(0) = 0x%x", kernel_task_port);
57 | INFO("KTRR already bypassed");
58 | goto done_0;
59 | }
60 | // Try to get the kernel task port using host_get_special_port(4). If this works, then an
61 | // exploit has already run but we still need to bypass KTRR.
62 | if (kernel_task_port == MACH_PORT_NULL) {
63 | mach_port_t host = mach_host_self();
64 | host_get_special_port(host, 0, 4, &kernel_task_port);
65 | mach_port_deallocate(mach_task_self(), host);
66 | if (kernel_task_port != MACH_PORT_NULL) {
67 | INFO("host_get_special_port(4) = 0x%x", kernel_task_port);
68 | }
69 | }
70 | // If we still don't have a kernel task port, then abort.
71 | if (kernel_task_port == MACH_PORT_NULL) {
72 | ERROR("Could not get kernel task port");
73 | goto done_0;
74 | }
75 | // Initialize our kernel function calling capability.
76 | ok = kernel_call_init();
77 | if (!ok) {
78 | ERROR("Could not initialize kernel_call subsystem");
79 | goto done_0;
80 | }
81 | // Bypass KTRR and remap the kernel as read/write.
82 | ok = have_ktrr_bypass();
83 | if (!ok) {
84 | ERROR("No KTRR bypass is available for this platform");
85 | goto done_1;
86 | }
87 | ktrr_bypass();
88 | // Apply kernel patches.
89 | apply_kernel_patches();
90 | // Check that we can call task_for_pid(0).
91 | mach_port_t tfp0 = MACH_PORT_NULL;
92 | task_for_pid(mach_task_self(), 0, &tfp0);
93 | INFO("task_for_pid(0) = 0x%x", tfp0);
94 | // Load the kernel extension.
95 | const char *kext_name = "ktrw_gdb_stub.ikext";
96 | char kext_path[1024];
97 | snprintf(kext_path, sizeof(kext_path), "%s/kexts/%s", bundle_path, kext_name);
98 | uint64_t kext_address = kext_load(kext_path, 0);
99 | INFO("Kext %s loaded at address 0x%016llx", kext_name, kext_address);
100 | done_1:
101 | // De-initialize our kernel function calling primitive.
102 | kernel_call_deinit();
103 | done_0:
104 | usleep(100000);
105 | exit(1);
106 | return YES;
107 | }
108 |
109 |
110 | - (void)applicationWillResignActive:(UIApplication *)application {
111 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
112 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
113 | }
114 |
115 |
116 | - (void)applicationDidEnterBackground:(UIApplication *)application {
117 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
118 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
119 | }
120 |
121 |
122 | - (void)applicationWillEnterForeground:(UIApplication *)application {
123 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
124 | }
125 |
126 |
127 | - (void)applicationDidBecomeActive:(UIApplication *)application {
128 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
129 | }
130 |
131 |
132 | - (void)applicationWillTerminate:(UIApplication *)application {
133 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
134 | }
135 |
136 |
137 | @end
138 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/app/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/ktrw_kext_loader/app/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ktrw_kext_loader/app/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/app/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/app/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/app/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #import
21 |
22 | @interface ViewController : UIViewController
23 |
24 |
25 | @end
26 |
27 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/app/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #import "ViewController.h"
21 |
22 | @interface ViewController ()
23 |
24 | @end
25 |
26 | @implementation ViewController
27 |
28 | - (void)viewDidLoad {
29 | [super viewDidLoad];
30 | // Do any additional setup after loading the view, typically from a nib.
31 | }
32 |
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/app/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #import
21 | #import "AppDelegate.h"
22 |
23 | int main(int argc, char * argv[]) {
24 | @autoreleasepool {
25 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/headers/IOKitLib.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef IOKITLIB__H_
21 | #define IOKITLIB__H_
22 |
23 | #include
24 | #include
25 |
26 | typedef mach_port_t io_object_t;
27 | typedef io_object_t io_connect_t;
28 | typedef io_object_t io_iterator_t;
29 | typedef io_object_t io_service_t;
30 |
31 | extern const mach_port_t kIOMasterPortDefault;
32 |
33 | kern_return_t
34 | IOObjectRelease(
35 | io_object_t object );
36 |
37 | io_object_t
38 | IOIteratorNext(
39 | io_iterator_t iterator );
40 |
41 | io_service_t
42 | IOServiceGetMatchingService(
43 | mach_port_t masterPort,
44 | CFDictionaryRef matching CF_RELEASES_ARGUMENT);
45 |
46 | kern_return_t
47 | IOServiceGetMatchingServices(
48 | mach_port_t masterPort,
49 | CFDictionaryRef matching CF_RELEASES_ARGUMENT,
50 | io_iterator_t * existing );
51 |
52 | kern_return_t
53 | IOServiceOpen(
54 | io_service_t service,
55 | task_port_t owningTask,
56 | uint32_t type,
57 | io_connect_t * connect );
58 |
59 | kern_return_t
60 | IOServiceClose(
61 | io_connect_t connect );
62 |
63 | kern_return_t
64 | IOConnectCallMethod(
65 | mach_port_t connection, // In
66 | uint32_t selector, // In
67 | const uint64_t *input, // In
68 | uint32_t inputCnt, // In
69 | const void *inputStruct, // In
70 | size_t inputStructCnt, // In
71 | uint64_t *output, // Out
72 | uint32_t *outputCnt, // In/Out
73 | void *outputStruct, // Out
74 | size_t *outputStructCnt) // In/Out
75 | AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER;
76 |
77 | kern_return_t
78 | IOConnectTrap6(io_connect_t connect,
79 | uint32_t index,
80 | uintptr_t p1,
81 | uintptr_t p2,
82 | uintptr_t p3,
83 | uintptr_t p4,
84 | uintptr_t p5,
85 | uintptr_t p6);
86 |
87 | CFMutableDictionaryRef
88 | IOServiceMatching(
89 | const char * name ) CF_RETURNS_RETAINED;
90 |
91 | #endif
92 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/headers/mach_vm.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef MACH_VM__H_
21 | #define MACH_VM__H_
22 |
23 | #include
24 |
25 | extern
26 | kern_return_t mach_vm_allocate
27 | (
28 | vm_map_t target,
29 | mach_vm_address_t *address,
30 | mach_vm_size_t size,
31 | int flags
32 | );
33 |
34 | extern
35 | kern_return_t mach_vm_deallocate
36 | (
37 | vm_map_t target,
38 | mach_vm_address_t address,
39 | mach_vm_size_t size
40 | );
41 |
42 | extern
43 | kern_return_t mach_vm_protect
44 | (
45 | vm_map_t target_task,
46 | mach_vm_address_t address,
47 | mach_vm_size_t size,
48 | boolean_t set_maximum,
49 | vm_prot_t new_protection
50 | );
51 |
52 | extern
53 | kern_return_t mach_vm_write
54 | (
55 | vm_map_t target_task,
56 | mach_vm_address_t address,
57 | vm_offset_t data,
58 | mach_msg_type_number_t dataCnt
59 | );
60 |
61 | extern
62 | kern_return_t mach_vm_read_overwrite
63 | (
64 | vm_map_t target_task,
65 | mach_vm_address_t address,
66 | mach_vm_size_t size,
67 | mach_vm_address_t data,
68 | mach_vm_size_t *outsize
69 | );
70 |
71 | extern
72 | kern_return_t mach_vm_remap
73 | (
74 | vm_map_t target_task,
75 | mach_vm_address_t *target_address,
76 | mach_vm_size_t size,
77 | mach_vm_offset_t mask,
78 | int flags,
79 | vm_map_t src_task,
80 | mach_vm_address_t src_address,
81 | boolean_t copy,
82 | vm_prot_t *cur_protection,
83 | vm_prot_t *max_protection,
84 | vm_inherit_t inheritance
85 | );
86 |
87 | extern
88 | kern_return_t mach_vm_region_recurse
89 | (
90 | vm_map_t target_task,
91 | mach_vm_address_t *address,
92 | mach_vm_size_t *size,
93 | natural_t *nesting_depth,
94 | vm_region_recurse_info_t info,
95 | mach_msg_type_number_t *infoCnt
96 | );
97 |
98 | #endif
99 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kernel/kernel_memory.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #define KERNEL_MEMORY_EXTERN
21 | #include "kernel_memory.h"
22 |
23 | #include
24 |
25 | #include "log.h"
26 | #include "mach_vm.h"
27 | #include "platform.h"
28 |
29 | // ---- Kernel memory functions -------------------------------------------------------------------
30 |
31 | uint64_t
32 | kernel_vm_allocate(size_t size) {
33 | mach_vm_address_t address = 0;
34 | kern_return_t kr = mach_vm_allocate(kernel_task_port, &address, size, VM_FLAGS_ANYWHERE);
35 | if (kr != KERN_SUCCESS) {
36 | ERROR("%s returned %d: %s", "mach_vm_allocate", kr, mach_error_string(kr));
37 | address = -1;
38 | } else {
39 | // Fault in each page.
40 | for (size_t offset = 0; offset < size; offset += page_size) {
41 | kernel_read64(address + offset);
42 | }
43 | }
44 | return address;
45 | }
46 |
47 | void
48 | kernel_vm_deallocate(uint64_t address, size_t size) {
49 | kern_return_t kr = mach_vm_deallocate(kernel_task_port, address, size);
50 | if (kr != KERN_SUCCESS) {
51 | WARNING("%s returned %d: %s", "mach_vm_deallocate", kr, mach_error_string(kr));
52 | }
53 | }
54 |
55 | bool
56 | kernel_vm_protect(uint64_t address, size_t size, vm_prot_t prot) {
57 | kern_return_t kr = mach_vm_protect(kernel_task_port, address, size, FALSE, prot);
58 | if (kr != KERN_SUCCESS) {
59 | ERROR("%s returned %d: %s", "mach_vm_protect", kr, mach_error_string(kr));
60 | return false;
61 | }
62 | return true;
63 | }
64 |
65 | void *
66 | kernel_vm_remap(uint64_t address, size_t size) {
67 | assert((address & (page_size - 1)) == 0);
68 | assert((size & (page_size - 1)) == 0);
69 | mach_vm_address_t target_address = 0;
70 | vm_prot_t cur_prot, max_prot;
71 | kern_return_t kr = mach_vm_remap(
72 | mach_task_self(),
73 | &target_address,
74 | size,
75 | 0,
76 | VM_FLAGS_ANYWHERE,
77 | kernel_task_port,
78 | address,
79 | FALSE,
80 | &cur_prot,
81 | &max_prot,
82 | VM_INHERIT_NONE);
83 | if (kr != KERN_SUCCESS) {
84 | ERROR("%s returned %d: %s", "mach_vm_remap", kr, mach_error_string(kr));
85 | return NULL;
86 | }
87 | return (void *)target_address;
88 | }
89 |
90 | bool
91 | kernel_read(uint64_t address, void *data, size_t size) {
92 | mach_vm_size_t size_out;
93 | kern_return_t kr = mach_vm_read_overwrite(kernel_task_port, address,
94 | size, (mach_vm_address_t) data, &size_out);
95 | if (kr != KERN_SUCCESS) {
96 | ERROR("%s returned %d: %s", "mach_vm_read_overwrite", kr, mach_error_string(kr));
97 | ERROR("could not %s address 0x%016llx", "read", address);
98 | return false;
99 | }
100 | if (size_out != size) {
101 | ERROR("partial read of address 0x%016llx: %llu of %zu bytes",
102 | address, size_out, size);
103 | return false;
104 | }
105 | return true;
106 | }
107 |
108 | bool
109 | kernel_write(uint64_t address, const void *data, size_t size) {
110 | const uint8_t *write_data = data;
111 | while (size > 0) {
112 | size_t write_size = size;
113 | if (write_size > page_size) {
114 | write_size = page_size;
115 | }
116 | kern_return_t kr = mach_vm_write(kernel_task_port, address,
117 | (mach_vm_address_t) write_data, (mach_msg_size_t) write_size);
118 | if (kr != KERN_SUCCESS) {
119 | ERROR("%s returned %d: %s", "mach_vm_write", kr, mach_error_string(kr));
120 | ERROR("could not %s address 0x%016llx", "write", address);
121 | return false;
122 | }
123 | address += write_size;
124 | write_data += write_size;
125 | size -= write_size;
126 | }
127 | return true;
128 | }
129 |
130 | uint8_t
131 | kernel_read8(uint64_t address) {
132 | uint8_t value;
133 | bool ok = kernel_read(address, &value, sizeof(value));
134 | if (!ok) {
135 | return -1;
136 | }
137 | return value;
138 | }
139 |
140 | uint16_t
141 | kernel_read16(uint64_t address) {
142 | uint16_t value;
143 | bool ok = kernel_read(address, &value, sizeof(value));
144 | if (!ok) {
145 | return -1;
146 | }
147 | return value;
148 | }
149 |
150 | uint32_t
151 | kernel_read32(uint64_t address) {
152 | uint32_t value;
153 | bool ok = kernel_read(address, &value, sizeof(value));
154 | if (!ok) {
155 | return -1;
156 | }
157 | return value;
158 | }
159 |
160 | uint64_t
161 | kernel_read64(uint64_t address) {
162 | uint64_t value;
163 | bool ok = kernel_read(address, &value, sizeof(value));
164 | if (!ok) {
165 | return -1;
166 | }
167 | return value;
168 | }
169 |
170 | bool
171 | kernel_write8(uint64_t address, uint8_t value) {
172 | return kernel_write(address, &value, sizeof(value));
173 | }
174 |
175 | bool
176 | kernel_write16(uint64_t address, uint16_t value) {
177 | return kernel_write(address, &value, sizeof(value));
178 | }
179 |
180 | bool
181 | kernel_write32(uint64_t address, uint32_t value) {
182 | return kernel_write(address, &value, sizeof(value));
183 | }
184 |
185 | bool
186 | kernel_write64(uint64_t address, uint64_t value) {
187 | return kernel_write(address, &value, sizeof(value));
188 | }
189 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kernel/kernel_memory.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef KERNEL_MEMORY__H_
21 | #define KERNEL_MEMORY__H_
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | #ifdef KERNEL_MEMORY_EXTERN
29 | #define extern KERNEL_MEMORY_EXTERN
30 | #endif
31 |
32 | /*
33 | * kernel_task_port
34 | *
35 | * Description:
36 | * The kernel task port.
37 | */
38 | extern mach_port_t kernel_task_port;
39 |
40 | /*
41 | * kernel_vm_allocate
42 | *
43 | * Description:
44 | * Allocate kernel virtual memory with mach_vm_allocate().
45 | */
46 | uint64_t kernel_vm_allocate(size_t size);
47 |
48 | /*
49 | * kernel_vm_deallocate
50 | *
51 | * Description:
52 | * Deallocate kernel virtual memory with mach_vm_deallocate().
53 | */
54 | void kernel_vm_deallocate(uint64_t address, size_t size);
55 |
56 | /*
57 | * kernel_vm_protect
58 | *
59 | * Description:
60 | * Set permissions on kernel virtual memory with mach_vm_protect().
61 | */
62 | bool kernel_vm_protect(uint64_t address, size_t size, vm_prot_t prot);
63 |
64 | /*
65 | * kernel_vm_remap
66 | *
67 | * Description:
68 | * Remap kernel memory into userspace. The address and size must be page-aligned.
69 | */
70 | void *kernel_vm_remap(uint64_t address, size_t size);
71 |
72 | /*
73 | * kernel_read
74 | *
75 | * Description:
76 | * Read data from kernel memory.
77 | */
78 | bool kernel_read(uint64_t address, void *data, size_t size);
79 |
80 | /*
81 | * kernel_write
82 | *
83 | * Description:
84 | * Write data to kernel memory.
85 | */
86 | bool kernel_write(uint64_t address, const void *data, size_t size);
87 |
88 | /*
89 | * kernel_read8
90 | *
91 | * Description:
92 | * Read a single byte from kernel memory. If the read fails, -1 is returned.
93 | */
94 | uint8_t kernel_read8(uint64_t address);
95 |
96 | /*
97 | * kernel_read16
98 | *
99 | * Description:
100 | * Read a 16-bit value from kernel memory. If the read fails, -1 is returned.
101 | */
102 | uint16_t kernel_read16(uint64_t address);
103 |
104 | /*
105 | * kernel_read32
106 | *
107 | * Description:
108 | * Read a 32-bit value from kernel memory. If the read fails, -1 is returned.
109 | */
110 | uint32_t kernel_read32(uint64_t address);
111 |
112 | /*
113 | * kernel_read64
114 | *
115 | * Description:
116 | * Read a 64-bit value from kernel memory. If the read fails, -1 is returned.
117 | */
118 | uint64_t kernel_read64(uint64_t address);
119 |
120 | /*
121 | * kernel_write8
122 | *
123 | * Description:
124 | * Write a single byte to kernel memory.
125 | */
126 | bool kernel_write8(uint64_t address, uint8_t value);
127 |
128 | /*
129 | * kernel_write16
130 | *
131 | * Description:
132 | * Write a 16-bit value to kernel memory.
133 | */
134 | bool kernel_write16(uint64_t address, uint16_t value);
135 |
136 | /*
137 | * kernel_write32
138 | *
139 | * Description:
140 | * Write a 32-bit value to kernel memory.
141 | */
142 | bool kernel_write32(uint64_t address, uint32_t value);
143 |
144 | /*
145 | * kernel_write64
146 | *
147 | * Description:
148 | * Write a 64-bit value to kernel memory.
149 | */
150 | bool kernel_write64(uint64_t address, uint64_t value);
151 |
152 | /*
153 | * kernel_ipc_port_lookup
154 | *
155 | * Description:
156 | * Get the address of the ipc_port and ipc_entry for a Mach port name.
157 | */
158 | bool kernel_ipc_port_lookup(uint64_t task, mach_port_name_t port_name,
159 | uint64_t *ipc_port, uint64_t *ipc_entry);
160 |
161 | #undef extern
162 |
163 | #endif
164 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kernel/kernel_parameters.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #define KERNEL_PARAMETERS_EXTERN PARAMETER_SHARED
21 | #include "kernel_parameters.h"
22 |
23 | #include "kernel_slide.h"
24 | #include "log.h"
25 | #include "platform_match.h"
26 |
27 | // ---- Offset initialization ---------------------------------------------------------------------
28 |
29 | static void
30 | offsets__iphone10_1__16C101() {
31 | kernel_slide_step = 0x4000;
32 | SIZE(ipc_entry) = 0x18;
33 | OFFSET(ipc_entry, ie_object) = 0;
34 | OFFSET(ipc_space, is_table_size) = 0x14;
35 | OFFSET(ipc_space, is_table) = 0x20;
36 | OFFSET(proc, p_list_next) = 0;
37 | OFFSET(proc, task) = 0x10;
38 | OFFSET(proc, p_pid) = 0x60;
39 | OFFSET(task, itk_space) = 0x300;
40 | OFFSET(task, bsd_info) = 0x358;
41 | STATIC_ADDRESS(kernel_base) = 0xFFFFFFF007004000;
42 | }
43 |
44 | static void
45 | offsets__iphone10_1__17B102() {
46 | kernel_slide_step = 0x4000;
47 | SIZE(ipc_entry) = 0x18;
48 | OFFSET(ipc_entry, ie_object) = 0;
49 | OFFSET(ipc_space, is_table_size) = 0x14;
50 | OFFSET(ipc_space, is_table) = 0x20;
51 | OFFSET(proc, p_list_next) = 0;
52 | OFFSET(proc, task) = 0x10;
53 | OFFSET(proc, p_pid) = 0x68;
54 | OFFSET(task, itk_space) = 0x320;
55 | OFFSET(task, bsd_info) = 0x380;
56 | STATIC_ADDRESS(kernel_base) = 0xFFFFFFF007004000;
57 | }
58 |
59 | static struct platform_initialization offsets[] = {
60 | { "iPhone10,1", "16C101-16G77", offsets__iphone10_1__16C101 },
61 | { "iPhone10,6", "16E227", offsets__iphone10_1__16C101 },
62 | { "iPhone10,1|iPhone10,4", "17B102-17C54", offsets__iphone10_1__17B102 },
63 | };
64 |
65 | // ---- Address initialization --------------------------------------------------------------------
66 |
67 | static void
68 | addresses__iphone10_1__16C101() {
69 | STATIC_ADDRESS(allproc) = 0xFFFFFFF0076D2B28;
70 | }
71 |
72 | static void
73 | addresses__iphone10_6__16E227() {
74 | STATIC_ADDRESS(allproc) = 0xFFFFFFF0076CF918;
75 | }
76 |
77 | static void
78 | addresses__iphone10_1__16G77() {
79 | STATIC_ADDRESS(allproc) = 0xFFFFFFF0076CF958;
80 | }
81 |
82 | static void
83 | addresses__iphone10_1__17B102() {
84 | STATIC_ADDRESS(allproc) = 0xFFFFFFF0091E6C50;
85 | }
86 |
87 | static void
88 | addresses__iphone10_1__17C54() {
89 | STATIC_ADDRESS(allproc) = 0xFFFFFFF0091EEC30;
90 | }
91 |
92 | static struct platform_initialization addresses[] = {
93 | { "iPhone10,1", "16C101", addresses__iphone10_1__16C101 },
94 | { "iPhone10,6", "16E227", addresses__iphone10_6__16E227 },
95 | { "iPhone10,1", "16G77", addresses__iphone10_1__16G77 },
96 | { "iPhone10,1|iPhone10,4", "17B102", addresses__iphone10_1__17B102 },
97 | { "iPhone10,1|iPhone10,4", "17C54", addresses__iphone10_1__17C54 },
98 | };
99 |
100 | // ---- Public API --------------------------------------------------------------------------------
101 |
102 | #define ARRAY_COUNT(x) (sizeof(x) / sizeof((x)[0]))
103 |
104 | bool
105 | kernel_parameters_init() {
106 | // Only run once.
107 | static bool initialized = false;
108 | if (initialized) {
109 | return true;
110 | }
111 | // Get general platform info.
112 | platform_init();
113 | // Initialize offsets.
114 | size_t count = run_platform_initializations(offsets, ARRAY_COUNT(offsets));
115 | if (count < 1) {
116 | ERROR("No kernel %s for %s %s", "offsets", platform.machine, platform.osversion);
117 | return false;
118 | }
119 | // Initialize addresses.
120 | count = run_platform_initializations(addresses, ARRAY_COUNT(addresses));
121 | if (count < 1) {
122 | ERROR("No kernel %s for %s %s", "addresses", platform.machine, platform.osversion);
123 | return false;
124 | }
125 | initialized = true;
126 | return true;
127 | }
128 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kernel/kernel_parameters.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef KERNEL_PARAMETERS__H_
21 | #define KERNEL_PARAMETERS__H_
22 |
23 | #include "parameters.h"
24 |
25 | #ifdef KERNEL_PARAMETERS_EXTERN
26 | #define extern KERNEL_PARAMETERS_EXTERN
27 | #endif
28 |
29 | // The static base address of the kernel.
30 | extern uint64_t STATIC_ADDRESS(kernel_base);
31 |
32 | // The kernel_slide granularity.
33 | extern uint64_t kernel_slide_step;
34 |
35 | // Parameters for struct ipc_entry.
36 | extern size_t SIZE(ipc_entry);
37 | extern size_t OFFSET(ipc_entry, ie_object);
38 |
39 | // Parameters for struct ipc_port.
40 | extern size_t OFFSET(ipc_port, ip_kobject);
41 |
42 | // Parameters for struct ipc_space.
43 | extern size_t OFFSET(ipc_space, is_table_size);
44 | extern size_t OFFSET(ipc_space, is_table);
45 |
46 | // Parameters for struct proc.
47 | extern size_t OFFSET(proc, p_list_next);
48 | extern size_t OFFSET(proc, task);
49 | extern size_t OFFSET(proc, p_pid);
50 |
51 | // Parameters for struct task.
52 | extern size_t OFFSET(task, itk_space);
53 | extern size_t OFFSET(task, bsd_info);
54 |
55 | // The static address of the allproc variable.
56 | extern uint64_t STATIC_ADDRESS(allproc);
57 |
58 | /*
59 | * kernel_parameters_init
60 | *
61 | * Description:
62 | * Initialize the parameters used in the kernel subsystem.
63 | */
64 | bool kernel_parameters_init(void);
65 |
66 | #undef extern
67 |
68 | #endif
69 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kernel/kernel_slide.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #define KERNEL_SLIDE_EXTERN
21 | #include "kernel_slide.h"
22 |
23 | #include
24 | #include
25 |
26 | #include "kernel_memory.h"
27 | #include "kernel_parameters.h"
28 | #include "kernel_tasks.h"
29 | #include "log.h"
30 | #include "mach_vm.h"
31 |
32 | // Check if the given address is the kernel base.
33 | static bool
34 | is_kernel_base(uint64_t base) {
35 | // Read the data at the base address as a Mach-O header.
36 | struct mach_header_64 header = {};
37 | bool ok = kernel_read(base, &header, sizeof(header));
38 | if (!ok) {
39 | return false;
40 | }
41 | // Validate that this looks like the kernel base. We don't check the CPU subtype since it
42 | // may not exactly match the current platform's CPU subtype (e.g. on iPhone10,1,
43 | // header.cpusubtype is CPU_SUBTYPE_ARM64_ALL while platform.cpu_subtype is
44 | // CPU_SUBTYPE_ARM64_V8).
45 | if (!(header.magic == MH_MAGIC_64
46 | && header.cputype == platform.cpu_type
47 | && header.filetype == MH_EXECUTE
48 | && header.ncmds > 2)) {
49 | return false;
50 | }
51 | return true;
52 | }
53 |
54 | // Call this once the kernel slide has been set up.
55 | static void
56 | did_set_kernel_slide() {
57 | INFO("KASLR slide is 0x%llx", kernel_slide);
58 | }
59 |
60 | // Some jailbreaks stash information about the kernel base in task_info(TASK_DYLD_INFO). Check to
61 | // see if this information is populated for the kernel_task_port.
62 | static bool
63 | check_task_dyld_info() {
64 | struct task_dyld_info info;
65 | mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
66 | kern_return_t kr = task_info(kernel_task_port,
67 | TASK_DYLD_INFO, (task_info_t) &info, &count);
68 | if (kr != KERN_SUCCESS) {
69 | return false;
70 | }
71 | uint64_t kernel_base = info.all_image_info_addr;
72 | if (is_kernel_base(kernel_base)) {
73 | kernel_slide = info.all_image_info_addr - STATIC_ADDRESS(kernel_base);
74 | goto found_kernel_slide;
75 | }
76 | kernel_base = STATIC_ADDRESS(kernel_base) + info.all_image_info_size;
77 | if (is_kernel_base(kernel_base)) {
78 | kernel_slide = info.all_image_info_size;
79 | goto found_kernel_slide;
80 | }
81 | return false;
82 | found_kernel_slide:
83 | did_set_kernel_slide();
84 | return true;
85 | }
86 |
87 | // Try to initialize the kernel slide from an address inside the kernel image (and after the kernel
88 | // Mach-O header).
89 | static bool
90 | init_with_kernel_image_address(uint64_t address) {
91 | // Find the highest possible kernel base address that could still correspond to the given
92 | // kernel image address.
93 | uint64_t base = STATIC_ADDRESS(kernel_base);
94 | assert(address > base);
95 | base = base + ((address - base) / kernel_slide_step) * kernel_slide_step;
96 | // Now walk backwards from that kernel base one kernel slide at a time until we find the
97 | // real kernel base.
98 | while (base >= STATIC_ADDRESS(kernel_base)) {
99 | bool found = is_kernel_base(base);
100 | if (found) {
101 | kernel_slide = base - STATIC_ADDRESS(kernel_base);
102 | did_set_kernel_slide();
103 | return true;
104 | }
105 | base -= kernel_slide_step;
106 | }
107 | return false;
108 | }
109 |
110 | // If we have current_task, then we can find the kernel slide easily by looking up the host port.
111 | static bool
112 | init_with_current_task() {
113 | // Get the address of the host port.
114 | mach_port_t host = mach_host_self();
115 | assert(MACH_PORT_VALID(host));
116 | uint64_t host_port;
117 | bool ok = kernel_ipc_port_lookup(current_task, host, &host_port, NULL);
118 | mach_port_deallocate(mach_task_self(), host);
119 | if (!ok) {
120 | return false;
121 | }
122 | // Get the address of realhost.
123 | uint64_t realhost = kernel_read64(host_port + OFFSET(ipc_port, ip_kobject));
124 | // Initialize with that address.
125 | return init_with_kernel_image_address(realhost);
126 | }
127 |
128 | // Try to find the kernel base using an unsafe heap scan to sample kernel pointers. As suggested by
129 | // the function name, this method is UNSAFE and may panic the device. It should only be used in the
130 | // absence of better options!
131 | static bool
132 | init_with_unsafe_heap_scan() {
133 | WARNING("Could not find the kernel base address");
134 | WARNING("Trying to find the kernel base address using an unsafe heap scan!");
135 | uint64_t kernel_region_base = 0xfffffff000000000;
136 | uint64_t kernel_region_end = 0xfffffffbffffc000;
137 | // Try and find a pointer in the kernel heap to data in the kernel image. We'll take the
138 | // smallest such pointer.
139 | uint64_t kernel_ptr = (uint64_t)(-1);
140 | mach_vm_address_t address = 0;
141 | for (;;) {
142 | // Get the next memory region.
143 | mach_vm_size_t size = 0;
144 | uint32_t depth = 2;
145 | struct vm_region_submap_info_64 info;
146 | mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64;
147 | kern_return_t kr = mach_vm_region_recurse(kernel_task_port, &address, &size,
148 | &depth, (vm_region_recurse_info_t) &info, &count);
149 | if (kr != KERN_SUCCESS) {
150 | break;
151 | }
152 | // Skip any region that is not on the heap, not in a submap, not readable and
153 | // writable, or not fully mapped.
154 | int prot = VM_PROT_READ | VM_PROT_WRITE;
155 | if (info.user_tag != 12
156 | || depth != 1
157 | || (info.protection & prot) != prot
158 | || info.pages_resident * 0x4000 != size) {
159 | goto next;
160 | }
161 | // Read the first word of each page in this region.
162 | for (size_t offset = 0; offset < size; offset += 0x4000) {
163 | uint64_t value = 0;
164 | bool ok = kernel_read(address + offset, &value, sizeof(value));
165 | if (ok
166 | && kernel_region_base <= value
167 | && value < kernel_region_end
168 | && value < kernel_ptr) {
169 | kernel_ptr = value;
170 | }
171 | }
172 | next:
173 | address += size;
174 | }
175 | // If we didn't find any such pointer, abort.
176 | if (kernel_ptr == (uint64_t)(-1)) {
177 | return false;
178 | }
179 | DEBUG_TRACE(1, "Found kernel pointer %p", (void *)kernel_ptr);
180 | // Now that we have a pointer, we want to scan pages until we reach the kernel's Mach-O
181 | // header. Unfortunately, the layout of the kernel differs on different iOS versions. iOS
182 | // 12.4 uses the old kernelcache format; on these kernelcaches, kernel_ptr will usually
183 | // point into one of the __PRELINK sections that lies before the Mach-O header in __TEXT.
184 | // On the other hand, iOS 13 uses the newer kernelcache format in which the __PRELINK
185 | // sections are empty and __TEXT is mapped first, and hence kernel_ptr lies after the
186 | // Mach-O header. We'll program for the newer kernelcache format.
187 | uint64_t page = kernel_ptr & ~0x3fff;
188 | for (;;) {
189 | bool found = is_kernel_base(page);
190 | if (found) {
191 | kernel_slide = page - STATIC_ADDRESS(kernel_base);
192 | did_set_kernel_slide();
193 | return true;
194 | }
195 | page -= 0x4000;
196 | }
197 | return false;
198 | }
199 |
200 | bool
201 | kernel_slide_init() {
202 | if (kernel_slide != 0) {
203 | return true;
204 | }
205 | // Initialize the parameters.
206 | bool ok = kernel_parameters_init();
207 | if (!ok) {
208 | return false;
209 | }
210 | // Check if the kernel base is stashed in task_info(TASK_DYLD_INFO).
211 | ok = check_task_dyld_info();
212 | if (ok) {
213 | return true;
214 | }
215 | // If we have current_task, then we can init with the address of the host port.
216 | if (current_task != 0) {
217 | ok = init_with_current_task();
218 | if (ok) {
219 | return true;
220 | }
221 | }
222 | // Try an unsafe heap scan. This is a last resort!
223 | ok = init_with_unsafe_heap_scan();
224 | if (ok) {
225 | return true;
226 | }
227 | // No available method.
228 | ERROR("Could not determine the kernel slide");
229 | return false;
230 | }
231 |
232 | bool
233 | kernel_slide_init_with_kernel_image_address(uint64_t address) {
234 | if (kernel_slide != 0) {
235 | return true;
236 | }
237 | bool ok = kernel_parameters_init();
238 | if (!ok) {
239 | return false;
240 | }
241 | ok = init_with_kernel_image_address(address);
242 | if (ok) {
243 | return true;
244 | }
245 | ERROR("Could not determine the kernel slide");
246 | return false;
247 | }
248 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kernel/kernel_slide.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef KERNEL_SLIDE__H_
21 | #define KERNEL_SLIDE__H_
22 |
23 | #include
24 | #include
25 |
26 | #ifdef KERNEL_SLIDE_EXTERN
27 | #define extern KERNEL_SLIDE_EXTERN
28 | #endif
29 |
30 | /*
31 | * kernel_slide
32 | *
33 | * Description:
34 | * The kASLR slide.
35 | */
36 | extern uint64_t kernel_slide;
37 |
38 | /*
39 | * kernel_slide_init
40 | *
41 | * Description:
42 | * Find the value of the kernel slide using task_info(TASK_DYLD_INFO) or current_task.
43 | */
44 | bool kernel_slide_init(void);
45 |
46 | /*
47 | * kernel_slide_init_with_kernel_image_address
48 | *
49 | * Description:
50 | * Find the value of the kernel slide using kernel_read(), starting with an address that is
51 | * known to reside within the kernel image.
52 | */
53 | bool kernel_slide_init_with_kernel_image_address(uint64_t address);
54 |
55 | #undef extern
56 |
57 | #endif
58 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kernel/kernel_tasks.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #define KERNEL_TASKS_EXTERN
21 | #include "kernel_tasks.h"
22 |
23 | #include
24 | #include
25 |
26 | #include "kernel_memory.h"
27 | #include "kernel_parameters.h"
28 | #include "kernel_slide.h"
29 | #include "log.h"
30 |
31 | // ---- Kernel task functions ---------------------------------------------------------------------
32 |
33 | bool
34 | kernel_ipc_port_lookup(uint64_t task, mach_port_name_t port_name,
35 | uint64_t *ipc_port, uint64_t *ipc_entry) {
36 | // Get the task's ipc_space.
37 | uint64_t itk_space = kernel_read64(task + OFFSET(task, itk_space));
38 | // Get the size of the table.
39 | uint32_t is_table_size = kernel_read32(itk_space + OFFSET(ipc_space, is_table_size));
40 | // Get the index of the port and check that it is in-bounds.
41 | uint32_t port_index = MACH_PORT_INDEX(port_name);
42 | if (port_index >= is_table_size) {
43 | return false;
44 | }
45 | // Get the space's is_table and compute the address of this port's entry.
46 | uint64_t is_table = kernel_read64(itk_space + OFFSET(ipc_space, is_table));
47 | uint64_t entry = is_table + port_index * SIZE(ipc_entry);
48 | if (ipc_entry != NULL) {
49 | *ipc_entry = entry;
50 | }
51 | // Get the address of the port if requested.
52 | if (ipc_port != NULL) {
53 | *ipc_port = kernel_read64(entry + OFFSET(ipc_entry, ie_object));
54 | }
55 | return true;
56 | }
57 |
58 | // ---- Initialization ----------------------------------------------------------------------------
59 |
60 | // Try to initialize kernel_task and current_task by walking the allproc list.
61 | static bool
62 | find_kernel_task_and_current_task() {
63 | if (STATIC_ADDRESS(allproc) == 0) {
64 | ERROR("Need allproc address to initialize tasks");
65 | return false;
66 | }
67 | uint64_t allproc = kernel_read64(STATIC_ADDRESS(allproc) + kernel_slide);
68 | uint64_t kernproc = 0;
69 | uint64_t current_proc = 0;
70 | int current_pid = getpid();
71 | uint64_t proc = allproc;
72 | for (;;) {
73 | if (proc == 0 || proc == -1) {
74 | break;
75 | }
76 | uint32_t pid = kernel_read32(proc + OFFSET(proc, p_pid));
77 | if (pid == 0) {
78 | kernproc = proc;
79 | } else if (pid == current_pid) {
80 | current_proc = proc;
81 | }
82 | proc = kernel_read64(proc + OFFSET(proc, p_list_next));
83 | if (proc == allproc) {
84 | break;
85 | }
86 | }
87 | if (kernproc != 0) {
88 | kernel_task = kernel_read64(kernproc + OFFSET(proc, task));
89 | }
90 | if (current_proc != 0) {
91 | current_task = kernel_read64(current_proc + OFFSET(proc, task));
92 | }
93 | return (kernel_task != 0 && current_task != 0);
94 | }
95 |
96 | bool
97 | kernel_tasks_init() {
98 | static bool initialized = false;
99 | if (initialized) {
100 | return true;
101 | }
102 | bool ok = kernel_parameters_init();
103 | if (!ok) {
104 | return false;
105 | }
106 | ok = find_kernel_task_and_current_task();
107 | if (!ok) {
108 | return false;
109 | }
110 | initialized = true;
111 | return true;
112 | }
113 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kernel/kernel_tasks.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef KERNEL_TASKS__H_
21 | #define KERNEL_TASKS__H_
22 |
23 | #include
24 | #include
25 |
26 | #ifdef KERNEL_TASKS_EXTERN
27 | #define extern KERNEL_TASKS_EXTERN
28 | #endif
29 |
30 | /*
31 | * kernel_task
32 | *
33 | * Description:
34 | * The address of the kernel_task in kernel memory.
35 | */
36 | extern uint64_t kernel_task;
37 |
38 | /*
39 | * current_task
40 | *
41 | * Description:
42 | * The address of the current task in kernel memory.
43 | */
44 | extern uint64_t current_task;
45 |
46 | /*
47 | * kernel_tasks_init
48 | *
49 | * Description:
50 | * Initialize kernel_task and current_task. kernel_slide must already be initialized.
51 | */
52 | bool kernel_tasks_init(void);
53 |
54 | #undef extern
55 |
56 | #endif
57 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kernel_call/kernel_call.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #include "kernel_call.h"
21 |
22 | #include
23 | #include
24 |
25 | #include "kernel_call_7_a11.h"
26 |
27 | // ---- Public API --------------------------------------------------------------------------------
28 |
29 | bool
30 | kernel_call_init() {
31 | bool ok = kernel_call_7_a11_init();
32 | if (!ok) {
33 | kernel_call_7_a11_deinit();
34 | }
35 | return ok;
36 | }
37 |
38 | void
39 | kernel_call_deinit() {
40 | kernel_call_7_a11_deinit();
41 | }
42 |
43 | uint32_t
44 | kernel_call_7(uint64_t function, size_t argument_count, ...) {
45 | assert(argument_count <= 7);
46 | uint64_t arguments[7];
47 | va_list ap;
48 | va_start(ap, argument_count);
49 | for (size_t i = 0; i < argument_count && i < 7; i++) {
50 | arguments[i] = va_arg(ap, uint64_t);
51 | }
52 | va_end(ap);
53 | return kernel_call_7v(function, argument_count, arguments);
54 | }
55 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kernel_call/kernel_call.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef KERNEL_CALL__H_
21 | #define KERNEL_CALL__H_
22 |
23 | #include
24 | #include
25 | #include
26 |
27 | /*
28 | * kernel_call_init
29 | *
30 | * Description:
31 | * Initialize kernel_call functions.
32 | */
33 | bool kernel_call_init(void);
34 |
35 | /*
36 | * kernel_call_deinit
37 | *
38 | * Description:
39 | * Deinitialize the kernel call subsystem and restore the kernel to a safe state.
40 | */
41 | void kernel_call_deinit(void);
42 |
43 | /*
44 | * kernel_call_7
45 | *
46 | * Description:
47 | * Call a kernel function with the specified arguments.
48 | *
49 | * Restrictions:
50 | * See kernel_call_7v().
51 | */
52 | uint32_t kernel_call_7(uint64_t function, size_t argument_count, ...);
53 |
54 | /*
55 | * kernel_call_7v
56 | *
57 | * Description:
58 | * Call a kernel function with the specified arguments.
59 | *
60 | * Restrictions:
61 | * At most 7 arguments can be passed.
62 | * arguments[0] must be nonzero.
63 | * The return value is truncated to 32 bits.
64 | */
65 | uint32_t kernel_call_7v(uint64_t function, size_t argument_count, const uint64_t arguments[]);
66 |
67 | #endif
68 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kernel_call/kernel_call_7_a11.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef KERNEL_CALL_7_A11__H_
21 | #define KERNEL_CALL_7_A11__H_
22 |
23 | #include
24 | #include
25 | #include
26 |
27 | /*
28 | * kernel_call_7_a11_init
29 | *
30 | * Description:
31 | * Initialize kernel_call_7 on A11 (non-PAC) devices. If this fails, still call
32 | * kernel_call_7_a11_deinit().
33 | *
34 | * Initializes:
35 | * kernel_call_parameters_init()
36 | * kernel_call_7v()
37 | */
38 | bool kernel_call_7_a11_init(void);
39 |
40 | /*
41 | * kernel_call_7_a11_deinit
42 | *
43 | * Description:
44 | * Deinitialize kernel_call_7 on A11 devices.
45 | */
46 | void kernel_call_7_a11_deinit(void);
47 |
48 | #endif
49 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kernel_call/kernel_call_parameters.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #define KERNEL_CALL_PARAMETERS_EXTERN PARAMETER_SHARED
21 | #include "kernel_call_parameters.h"
22 |
23 | #include "kernel_slide.h"
24 | #include "log.h"
25 | #include "platform_match.h"
26 |
27 | // ---- Offset initialization ---------------------------------------------------------------------
28 |
29 | static void
30 | offsets__iphone10_1__16C101() {
31 | OFFSET(ipc_port, ip_kobject) = 104;
32 | OFFSET(proc, p_ucred) = 0xf8;
33 | OFFSET(task, bsd_info) = 0x358;
34 | SIZE(IOExternalTrap) = 24;
35 | OFFSET(IOExternalTrap, object) = 0;
36 | OFFSET(IOExternalTrap, function) = 8;
37 | OFFSET(IOExternalTrap, offset) = 16;
38 | OFFSET(IORegistryEntry, reserved) = 16;
39 | OFFSET(IORegistryEntry__ExpansionData, fRegistryEntryID) = 8;
40 | VTABLE_INDEX(IOUserClient, getExternalTrapForIndex) = 0x5b8 / 8;
41 | VTABLE_INDEX(IOUserClient, getTargetAndTrapForIndex) = 0x5c0 / 8;
42 | }
43 |
44 | static void
45 | offsets__iphone10_1__17B102() {
46 | OFFSET(ipc_port, ip_kobject) = 104;
47 | OFFSET(proc, p_ucred) = 0x100;
48 | OFFSET(task, bsd_info) = 0x380;
49 | SIZE(IOExternalTrap) = 24;
50 | OFFSET(IOExternalTrap, object) = 0;
51 | OFFSET(IOExternalTrap, function) = 8;
52 | OFFSET(IOExternalTrap, offset) = 16;
53 | OFFSET(IORegistryEntry, reserved) = 16;
54 | OFFSET(IORegistryEntry__ExpansionData, fRegistryEntryID) = 8;
55 | VTABLE_INDEX(IOUserClient, getExternalTrapForIndex) = 0x5c0 / 8;
56 | VTABLE_INDEX(IOUserClient, getTargetAndTrapForIndex) = 0x5c8 / 8;
57 | }
58 |
59 | static struct platform_initialization offsets[] = {
60 | { "iPhone10,1", "16C101-16G77", offsets__iphone10_1__16C101 },
61 | { "iPhone10,6", "16E227", offsets__iphone10_1__16C101 },
62 | { "iPhone10,1|iPhone10,4", "17B102-17C54", offsets__iphone10_1__17B102 },
63 | };
64 |
65 | // ---- Address initialization --------------------------------------------------------------------
66 |
67 | #define SLIDE(address) (address == 0 ? 0 : address + kernel_slide)
68 |
69 | static void
70 | addresses__iphone10_1__16C101() {
71 | ADDRESS(mov_x0_x4__br_x5) = SLIDE(0xFFFFFFF006580164);
72 | ADDRESS(IOUserClient__vtable) = SLIDE(0xFFFFFFF0070CC648);
73 | ADDRESS(IORegistryEntry__getRegistryEntryID) = SLIDE(0xFFFFFFF00759424C);
74 | }
75 |
76 | static void
77 | addresses__iphone10_6__16E227() {
78 | ADDRESS(mov_x0_x4__br_x5) = SLIDE(0xFFFFFFF00659E068);
79 | ADDRESS(IOUserClient__vtable) = SLIDE(0xFFFFFFF0070CC818);
80 | ADDRESS(IORegistryEntry__getRegistryEntryID) = SLIDE(0xFFFFFFF0075931F4);
81 | }
82 |
83 | static void
84 | addresses__iphone10_1__16G77() {
85 | ADDRESS(mov_x0_x4__br_x5) = SLIDE(0xFFFFFFF00658D30C);
86 | ADDRESS(IOUserClient__vtable) = SLIDE(0xFFFFFFF0070CC780);
87 | ADDRESS(IORegistryEntry__getRegistryEntryID) = SLIDE(0xFFFFFFF007594320);
88 | }
89 |
90 | static void
91 | addresses__iphone10_1__17B102() {
92 | ADDRESS(IOUserClient__vtable) = SLIDE(0xFFFFFFF00791CCD8);
93 | ADDRESS(IORegistryEntry__getRegistryEntryID) = SLIDE(0xFFFFFFF0080FFDE0);
94 | }
95 |
96 | static void
97 | addresses__iphone10_1__17C54() {
98 | ADDRESS(IOUserClient__vtable) = SLIDE(0xFFFFFFF007920CD8);
99 | ADDRESS(IORegistryEntry__getRegistryEntryID) = SLIDE(0xFFFFFFF00810696C);
100 | }
101 |
102 | static struct platform_initialization addresses[] = {
103 | { "iPhone10,1", "16C101", addresses__iphone10_1__16C101 },
104 | { "iPhone10,6", "16E227", addresses__iphone10_6__16E227 },
105 | { "iPhone10,1", "16G77", addresses__iphone10_1__16G77 },
106 | { "iPhone10,1|iPhone10,4", "17B102", addresses__iphone10_1__17B102 },
107 | { "iPhone10,1|iPhone10,4", "17C54", addresses__iphone10_1__17C54 },
108 | };
109 |
110 | // ---- Public API --------------------------------------------------------------------------------
111 |
112 | #define ARRAY_COUNT(x) (sizeof(x) / sizeof((x)[0]))
113 |
114 | bool
115 | kernel_call_parameters_init() {
116 | bool ok = kernel_slide_init();
117 | if (!ok) {
118 | return false;
119 | }
120 | size_t count = run_platform_initializations(offsets, ARRAY_COUNT(offsets));
121 | if (count < 1) {
122 | ERROR("No kernel_call %s for %s %s", "offsets",
123 | platform.machine, platform.osversion);
124 | return false;
125 | }
126 | count = run_platform_initializations(addresses, ARRAY_COUNT(addresses));
127 | if (count < 1) {
128 | ERROR("No kernel_call %s for %s %s", "addresses",
129 | platform.machine, platform.osversion);
130 | return false;
131 | }
132 | return true;
133 | }
134 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kernel_call/kernel_call_parameters.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef KERNEL_CALL_PARAMETERS__H_
21 | #define KERNEL_CALL_PARAMETERS__H_
22 |
23 | #include "parameters.h"
24 |
25 | #ifdef KERNEL_CALL_PARAMETERS_EXTERN
26 | #define extern KERNEL_CALL_PARAMETERS_EXTERN
27 | #endif
28 |
29 | extern uint64_t ADDRESS(mov_x0_x4__br_x5);
30 | extern uint64_t ADDRESS(IOUserClient__vtable);
31 | extern uint64_t ADDRESS(IORegistryEntry__getRegistryEntryID);
32 |
33 | // Parameters for struct ipc_port.
34 | extern size_t OFFSET(ipc_port, ip_kobject);
35 |
36 | // Parameters for struct proc.
37 | extern size_t OFFSET(proc, p_ucred);
38 |
39 | // Parameters for struct task.
40 | extern size_t OFFSET(task, bsd_info);
41 |
42 | // Parameters for IOExternalTrap.
43 | extern size_t SIZE(IOExternalTrap);
44 | extern size_t OFFSET(IOExternalTrap, object);
45 | extern size_t OFFSET(IOExternalTrap, function);
46 | extern size_t OFFSET(IOExternalTrap, offset);
47 |
48 | // Parameters for IORegistryEntry.
49 | extern size_t OFFSET(IORegistryEntry, reserved);
50 | extern size_t OFFSET(IORegistryEntry__ExpansionData, fRegistryEntryID);
51 |
52 | // Parameters for IOUserClient.
53 | extern uint32_t VTABLE_INDEX(IOUserClient, getExternalTrapForIndex);
54 | extern uint32_t VTABLE_INDEX(IOUserClient, getTargetAndTrapForIndex);
55 |
56 | /*
57 | * kernel_call_parameters_init
58 | *
59 | * Description:
60 | * Initialize the addresses used in the kernel_call subsystem.
61 | */
62 | bool kernel_call_parameters_init(void);
63 |
64 | #undef extern
65 |
66 | #endif
67 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kernel_patches/kernel_patches.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #include "kernel_patches.h"
21 |
22 | #include "kernel_memory.h"
23 | #include "kernel_slide.h"
24 | #include "log.h"
25 | #include "platform_match.h"
26 |
27 | // A structure to describe a patch consisting of a single instruction substitution.
28 | struct instruction_substitution {
29 | uint64_t address;
30 | uint32_t instruction;
31 | };
32 |
33 | // A helper macro to get the number of elements in a static array.
34 | #define ARRAY_COUNT(x) (sizeof(x) / sizeof((x)[0]))
35 |
36 | // ---- Kernel patches ----------------------------------------------------------------------------
37 |
38 | // A helper to define a branch instruction. This only works for short ranges!
39 | #define BRANCH(source, target) (0x14000000 | (0x03FFFFFF & (uint32_t)(((int64_t)target - (int64_t)source) / 4)))
40 |
41 | static void
42 | task_for_pid_0__iPhone10_1__16C101() {
43 | INFO("Patching task_for_pid(0)");
44 | const struct instruction_substitution code_patches[] = {
45 | // task_for_pid():
46 | // "if (pid == 0)" -> NOP
47 | { 0xFFFFFFF007500F20, 0xD503201F },
48 | // task_for_pid():
49 | // "task_for_pid_posix_check(p)" -> NOP
50 | { 0xFFFFFFF007500F44, 0xD503201F },
51 | // task_for_pid():
52 | // Skip the inlined code of mac_proc_check_get_task().
53 | // ADRP X23, #mac_policy_list@PAGE -> B 0xFFFFFFF0075010F8
54 | { 0xFFFFFFF007500F5C, BRANCH(0xFFFFFFF007500F5C, 0xFFFFFFF0075010F8) },
55 | // convert_port_to_locked_task():
56 | // "if (caller == victim)" -> "if (caller == caller)"
57 | // CMP X24, X23 -> CMP X24, X24
58 | { 0xFFFFFFF007119530, 0xEB18031F },
59 | // convert_port_to_task_with_exec_token():
60 | // "if (caller == victim)" -> "if (caller == caller)"
61 | // CMP X8, X21 -> CMP X8, X8
62 | { 0xFFFFFFF007119730, 0xEB08011F },
63 | };
64 | for (size_t i = 0; i < ARRAY_COUNT(code_patches); i++) {
65 | uint64_t address = code_patches[i].address + kernel_slide;
66 | kernel_write32(address, code_patches[i].instruction);
67 | }
68 | }
69 |
70 | static void
71 | i_can_has_debugger__iPhone10_1__16C101() {
72 | INFO("Enabling PE_i_can_has_debugger()");
73 | uint64_t debug_enabled = 0xFFFFFFF00702D430 + kernel_slide;
74 | kernel_write32(debug_enabled, 1);
75 | }
76 |
77 | // A list of kernel patches to apply by platform.
78 | static struct platform_initialization kernel_patches[] = {
79 | { "iPhone10,1", "16C101", task_for_pid_0__iPhone10_1__16C101 },
80 | { "iPhone10,1", "16C101", i_can_has_debugger__iPhone10_1__16C101 },
81 | };
82 |
83 | // ---- API ---------------------------------------------------------------------------------------
84 |
85 | void
86 | apply_kernel_patches() {
87 | run_platform_initializations(kernel_patches, ARRAY_COUNT(kernel_patches));
88 | }
89 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kernel_patches/kernel_patches.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef KERNEL_PATCHES__H_
21 | #define KERNEL_PATCHES__H_
22 |
23 | /*
24 | * apply_kernel_patches
25 | *
26 | * Description:
27 | * Apply the kernel patches.
28 | */
29 | void apply_kernel_patches(void);
30 |
31 | #endif
32 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kernel_symbols/iPhone10,1_16C101.txt:
--------------------------------------------------------------------------------
1 | __disable_preemption 0xFFFFFFF00720424C
2 | __enable_preemption 0xFFFFFFF007204260
3 | __mh_execute_header 0xFFFFFFF007004000
4 | _const_boot_args 0xFFFFFFF0070B9548
5 | _IOSleep 0xFFFFFFF007588B4C
6 | _kernel_map 0xFFFFFFF007666080
7 | _kernel_memory_allocate 0xFFFFFFF007197F4C
8 | _kernel_thread_start 0xFFFFFFF0071435EC
9 | _ml_nofault_copy 0xFFFFFFF00720A5B0
10 | _panic 0xFFFFFFF007112278
11 | _paniclog_append_noflush 0xFFFFFFF007120568
12 | _thread_deallocate 0xFFFFFFF007140FFC
13 | _vsnprintf 0xFFFFFFF0074A1ED8
14 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kernel_symbols/iPhone10,1_16G77.txt:
--------------------------------------------------------------------------------
1 | __disable_preemption 0xFFFFFFF007203050
2 | __enable_preemption 0xFFFFFFF007203064
3 | __mh_execute_header 0xFFFFFFF007004000
4 | _const_boot_args 0xFFFFFFF0070B9558
5 | _IOSleep 0xFFFFFFF007589040
6 | _kernel_map 0xFFFFFFF007663080
7 | _kernel_memory_allocate 0xFFFFFFF0071995FC
8 | _kernel_thread_start 0xFFFFFFF007143F58
9 | _ml_nofault_copy 0xFFFFFFF007209324
10 | _panic 0xFFFFFFF00711207C
11 | _paniclog_append_noflush 0xFFFFFFF0071209B0
12 | _thread_deallocate 0xFFFFFFF0071419B4
13 | _vsnprintf 0xFFFFFFF0074A2384
14 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kernel_symbols/iPhone10,6_16E227.txt:
--------------------------------------------------------------------------------
1 | __disable_preemption 0xFFFFFFF007202A84
2 | __enable_preemption 0xFFFFFFF007202A98
3 | __mh_execute_header 0xFFFFFFF007004000
4 | _const_boot_args 0xFFFFFFF0070B9558
5 | _IOSleep 0xFFFFFFF007587F14
6 | _kernel_map 0xFFFFFFF007663080
7 | _kernel_memory_allocate 0xFFFFFFF007198050
8 | _kernel_thread_start 0xFFFFFFF007143B3C
9 | _ml_nofault_copy 0xFFFFFFF007208D4C
10 | _panic 0xFFFFFFF007111E7C
11 | _paniclog_append_noflush 0xFFFFFFF00712059C
12 | _thread_deallocate 0xFFFFFFF00714159C
13 | _vsnprintf 0xFFFFFFF0074A1138
14 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kext_load/kext_load.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef KEXT_LOAD__H_
21 | #define KEXT_LOAD__H_
22 |
23 | #include
24 | #include
25 |
26 | /*
27 | * kext_load_set_kernel_symbol_database
28 | *
29 | * Description:
30 | * Set the path to the kernel symbols database.
31 | */
32 | bool kext_load_set_kernel_symbol_database(const char *path);
33 |
34 | /*
35 | * kext_load
36 | *
37 | * Description:
38 | * Dynamically load a Mach-O file into the kernel and call its entry point function. The
39 | * address of the kernel extension in kernel memory is returned.
40 | *
41 | * The "kext" file isn't a true kext in the sense of a macOS kernel extension. Rather, it's a
42 | * binary that conforms to certain formatting standards that allow us to map it into kernel
43 | * memory and resolve its symbols from a kernel image symbol database.
44 | *
45 | * Compiling the kext:
46 | * In order to be loadable, the Mach-O must be compiled as position-independent arm64. Use the
47 | * following CFLAGS:
48 | *
49 | * -arch arm64 -fno-builtin -fno-common -mkernel
50 | *
51 | * For linking you'll want the following LDFLAGS:
52 | *
53 | * -Xlinker -kext -nostdlib -Xlinker -fatal_warnings
54 | *
55 | * In the source of the kext, mark any kernel symbols that need to be resolved at link time
56 | * with:
57 | *
58 | * extern __attribute__((weak_import))
59 | *
60 | * The entry point should be a function _kext_start() with the following prototype:
61 | *
62 | * uint32_t _kext_start(uint64_t argument)
63 | *
64 | * Linking the kext:
65 | * Symbols in the kext are resolved to their runtime values by consulting the appropriate
66 | * symbol database for the device and OS version located in the kernel_symbols/ directory.
67 | *
68 | * In the kext, you can dynamically check whether the external symbol was resolved by testing
69 | * its address: if the address of the symbol is 0, then it is unresolved and should not be
70 | * used.
71 | *
72 | * Loading the kext:
73 | * The kext is loaded into kernel memory and then virtual memory protections are set according
74 | * to the protections in each segment command. The _kext_start() function is then called from
75 | * userspace using kernel_call_7(). _kext_start() will be supplied the 64-bit argument value
76 | * given to kext_load().
77 | *
78 | * Unloading the kext:
79 | * TODO: Not yet supported.
80 | */
81 | uint64_t kext_load(const char *file, uint64_t argument);
82 |
83 | #endif
84 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kext_load/resolve_symbol.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #include "resolve_symbol.h"
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | #include "bundle_path.h"
28 | #include "log.h"
29 | #include "map_file.h"
30 | #include "platform.h"
31 |
32 |
33 | // ---- Internal functions ------------------------------------------------------------------------
34 |
35 | // The mapped database file.
36 | static void *symbol_database = NULL;
37 | static size_t symbol_database_size = 0;
38 |
39 | /*
40 | * lookup_symbol
41 | *
42 | * Description:
43 | * Parses the memory-mapped database file line-by-line looking for the matching symbol.
44 | */
45 | static uint64_t
46 | lookup_symbol(const char *name) {
47 | const char *str = symbol_database;
48 | const char *const end = str + symbol_database_size;
49 | // Each iteration of this loop starts at the beginning of a line.
50 | for (;;) {
51 | char ch;
52 | // At the start of the line. Skip any leading whitespace.
53 | for (;;) {
54 | if (str >= end) {
55 | return 0;
56 | }
57 | ch = *str;
58 | if (ch != ' ' && ch != '\t') {
59 | break;
60 | }
61 | str++;
62 | }
63 | // At the symbol name.
64 | const char *p = name;
65 | for (;;) {
66 | if (*p == 0) {
67 | break;
68 | }
69 | if (*p != ch) {
70 | goto next_line;
71 | }
72 | p++;
73 | str++;
74 | if (str >= end) {
75 | return 0;
76 | }
77 | ch = *str;
78 | }
79 | // Matched the name. Consume some whitespace.
80 | if (ch != ' ' && ch != '\t') {
81 | // Not a match.
82 | goto next_line;
83 | }
84 | for (;;) {
85 | str++;
86 | if (str >= end) {
87 | return 0;
88 | }
89 | ch = *str;
90 | if (ch != ' ' && ch != '\t') {
91 | break;
92 | }
93 | }
94 | // Matched the name plus whitespace. Extract the value.
95 | uint64_t value = 0;
96 | if (str + 2 + 16 > end) {
97 | goto next_line;
98 | }
99 | if (ch != '0') {
100 | goto next_line;
101 | }
102 | str++;
103 | ch = *str;
104 | if (ch != 'x') {
105 | goto next_line;
106 | }
107 | str++;
108 | ch = *str;
109 | for (size_t i = 0;;) {
110 | uint64_t digit;
111 | if ('0' <= ch && ch <= '9') {
112 | digit = ch - '0';
113 | } else if ('a' <= ch && ch <= 'f') {
114 | digit = ch - 'a' + 0xa;
115 | } else if ('A' <= ch && ch <= 'F') {
116 | digit = ch - 'A' + 0xa;
117 | } else {
118 | goto next_line;
119 | }
120 | value = (value << 4) | digit;
121 | i++;
122 | str++;
123 | if (i >= 16) {
124 | break;
125 | }
126 | if (str >= end) {
127 | return 0;
128 | }
129 | ch = *str;
130 | }
131 | // Alright, we have a value! Make sure that we don't have more.
132 | if (str >= end) {
133 | return value;
134 | }
135 | ch = *str;
136 | if (ch != ' ' && ch != '\t' && ch != '\n') {
137 | WARNING("Invalid value for symbol %s", name);
138 | return 0;
139 | }
140 | // Correctly formatted value!
141 | return value;
142 | // Find the next newline character and then skip it to start the next line.
143 | next_line:
144 | for (;;) {
145 | if (str >= end) {
146 | return 0;
147 | }
148 | if (ch == '\n') {
149 | break;
150 | }
151 | str++;
152 | ch = *str;
153 | }
154 | str++;
155 | }
156 | }
157 |
158 | // ---- Public API --------------------------------------------------------------------------------
159 |
160 | bool
161 | load_symbol_database(const char *database_path) {
162 | if (symbol_database != NULL) {
163 | return true;
164 | }
165 | platform_init();
166 | char symbol_file_path[1024];
167 | snprintf(symbol_file_path, sizeof(symbol_file_path), "%s/%s_%s.txt",
168 | database_path, platform.machine, platform.osversion);
169 | symbol_database = map_file(symbol_file_path, &symbol_database_size);
170 | if (symbol_database == NULL) {
171 | WARNING("No kernel symbol database for %s %s", platform.machine, platform.osversion);
172 | return false;
173 | }
174 | return true;
175 | }
176 |
177 | uint64_t
178 | resolve_symbol(const char *symbol) {
179 | return lookup_symbol(symbol);
180 | }
181 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/kext_load/resolve_symbol.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef RESOLVE_SYMBOL__H_
21 | #define RESOLVE_SYMBOL__H_
22 |
23 | #include
24 | #include
25 |
26 | /*
27 | * load_symbol_database
28 | *
29 | * Description:
30 | * Tries to load the symbol database for this platform.
31 | */
32 | bool load_symbol_database(const char *database_path);
33 |
34 | /*
35 | * resolve_symbol
36 | *
37 | * Description:
38 | * Resolves a symbol in the kernel image to its static (unslid) address.
39 | *
40 | * The appropriate database must be loaded first with load_symbol_database().
41 | */
42 | uint64_t resolve_symbol(const char *symbol);
43 |
44 | #endif
45 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/ktrr/ktrr_bypass.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef KTRR_BYPASS__H_
21 | #define KTRR_BYPASS__H_
22 |
23 | #include
24 | #include
25 | #include
26 |
27 | /*
28 | * have_ktrr_bypass
29 | *
30 | * Description:
31 | * Checks whether a KTRR bypass is available for this platform. Only A11 devices are confirmed
32 | * to have the necessary debug registers accessible.
33 | */
34 | bool have_ktrr_bypass(void);
35 |
36 | /*
37 | * ktrr_bypass
38 | *
39 | * Description:
40 | * Disables KTRR and remaps the RoRgn to be writable.
41 | *
42 | * Implementation:
43 | * KTRR is disabled using the CoreSight External Debug registers along with a proprietary
44 | * register called DBGWRAP. These registers allow placing a CPU core into a debug state in
45 | * which register values can be inspected and modified and execution can be single-stepped. By
46 | * single-stepping through execution of the reset vector after a core resets, we can subvert
47 | * initialization of KTRR and specify a custom page table base to be written to TTBR1_EL1,
48 | * allowing the kernel to be remapped to new physical pages outside of the AMCC-protected
49 | * RoRgn.
50 | *
51 | * Limitations:
52 | * Note that these changes only persist while the device is plugged in and active; changes may
53 | * be lost (leaking memory and possibly leaving the system unstable) anytime after sleeping.
54 | * In particular, once the debug power domain is switched off, the debug registers will reset,
55 | * losing state which prevents the CPU cores from resetting. It is possible to work around
56 | * this restriction for a fully persistent KTRR bypass, but I have not implemented that here.
57 | */
58 | void ktrr_bypass(void);
59 |
60 | /*
61 | * ktrr_vm_protect
62 | *
63 | * Description:
64 | * Set virtual memory protection on an address range.
65 | *
66 | * This is stronger than kernel_vm_protect() since it can be used to make memory executable.
67 | */
68 | void ktrr_vm_protect(uint64_t address, size_t size, int prot);
69 |
70 | #endif
71 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/ktrr/ktrr_bypass_parameters.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #define KTRR_BYPASS_PARAMETERS_EXTERN PARAMETER_SHARED
21 | #include "ktrr_bypass_parameters.h"
22 |
23 | #include
24 |
25 | #include "kernel_memory.h"
26 | #include "kernel_slide.h"
27 | #include "log.h"
28 | #include "platform_match.h"
29 |
30 | // ---- Offset initialization ---------------------------------------------------------------------
31 |
32 | static void
33 | offsets__iphone10_1__16C101() {
34 | SIZE(cpu_data_entry) = 16;
35 | OFFSET(cpu_data_entry, cpu_data_vaddr) = 8;
36 | OFFSET(cpu_data, cpu_regmap_paddr) = 61 * 8;
37 | OFFSET(cpu_data, ed_mmio) = 57 * 8;
38 | OFFSET(cpu_data, utt_mmio) = 60 * 8;
39 | }
40 |
41 | static void
42 | offsets__iphone10_1__17B102() {
43 | SIZE(cpu_data_entry) = 16;
44 | OFFSET(cpu_data_entry, cpu_data_vaddr) = 8;
45 | OFFSET(cpu_data, cpu_regmap_paddr) = 63 * 8;
46 | OFFSET(cpu_data, ed_mmio) = 59 * 8;
47 | OFFSET(cpu_data, utt_mmio) = 62 * 8;
48 | }
49 |
50 | static struct platform_initialization offsets[] = {
51 | { "iPhone10,1", "16C101-16G77", offsets__iphone10_1__16C101 },
52 | { "iPhone10,6", "16E227", offsets__iphone10_1__16C101 },
53 | { "iPhone10,1|iPhone10,4", "17B102-17C54", offsets__iphone10_1__17B102 },
54 | };
55 |
56 | // ---- KTRR parameter initialization -------------------------------------------------------------
57 |
58 | #define SLIDE(address) (address == 0 ? 0 : address + kernel_slide)
59 |
60 | static void
61 | parameters__iphone10_1__16C101() {
62 | gPhysBase = kernel_read64(SLIDE(0xFFFFFFF0070B96D8));
63 | gVirtBase = kernel_read64(SLIDE(0xFFFFFFF0070B96E0));
64 | rorgn_begin = kernel_read64(SLIDE(0xFFFFFFF0070B99B8));
65 | rorgn_end = kernel_read64(SLIDE(0xFFFFFFF0070B99C0));
66 | cpu_ttep = kernel_read64(SLIDE(0xFFFFFFF0070B9488));
67 | kernel_pmap = kernel_read64(SLIDE(0xFFFFFFF0070B9468));
68 | ADDRESS(pmap_find_phys) = SLIDE(0xFFFFFFF0071F88AC);
69 | ADDRESS(ml_phys_read_data) = SLIDE(0xFFFFFFF007203CAC);
70 | ADDRESS(ml_phys_write_data) = SLIDE(0xFFFFFFF007203F14);
71 | ADDRESS(ml_io_map) = SLIDE(0xFFFFFFF0072095CC);
72 | ADDRESS(ldr_w0_x0__ret) = SLIDE(0xFFFFFFF00711EE60);
73 | ADDRESS(str_w1_x0__ret) = SLIDE(0xFFFFFFF0061DF26C);
74 | ADDRESS(CpuDataEntries) = SLIDE(0xFFFFFFF007634000);
75 | }
76 |
77 | static void
78 | parameters__iphone10_6__16E227() {
79 | gPhysBase = kernel_read64(SLIDE(0xFFFFFFF0070B96E8));
80 | gVirtBase = kernel_read64(SLIDE(0xFFFFFFF0070B96F0));
81 | rorgn_begin = kernel_read64(SLIDE(0xFFFFFFF0070B99C8));
82 | rorgn_end = kernel_read64(SLIDE(0xFFFFFFF0070B99D0));
83 | cpu_ttep = kernel_read64(SLIDE(0xFFFFFFF0070B9498));
84 | kernel_pmap = kernel_read64(SLIDE(0xFFFFFFF0070B9478));
85 | ADDRESS(pmap_find_phys) = SLIDE(0xFFFFFFF0071F74A4);
86 | ADDRESS(ml_phys_read_data) = SLIDE(0xFFFFFFF0072024F4);
87 | ADDRESS(ml_phys_write_data) = SLIDE(0xFFFFFFF007202754);
88 | ADDRESS(ml_io_map) = SLIDE(0xFFFFFFF007207EE0);
89 | ADDRESS(ldr_w0_x0__ret) = SLIDE(0xFFFFFFF00711EE6C);
90 | ADDRESS(str_w1_x0__ret) = SLIDE(0xFFFFFFF0061C600C);
91 | ADDRESS(CpuDataEntries) = SLIDE(0xFFFFFFF0076ACD38);
92 | }
93 |
94 | static void
95 | parameters__iphone10_1__16G77() {
96 | gPhysBase = kernel_read64(SLIDE(0xFFFFFFF0070B96E8));
97 | gVirtBase = kernel_read64(SLIDE(0xFFFFFFF0070B96F0));
98 | rorgn_begin = kernel_read64(SLIDE(0xFFFFFFF0070B99C8));
99 | rorgn_end = kernel_read64(SLIDE(0xFFFFFFF0070B99D0));
100 | cpu_ttep = kernel_read64(SLIDE(0xFFFFFFF0070B9498));
101 | kernel_pmap = kernel_read64(SLIDE(0xFFFFFFF0070B9478));
102 | ADDRESS(pmap_find_phys) = SLIDE(0xFFFFFFF0071F75D4);
103 | ADDRESS(ml_phys_read_data) = SLIDE(0xFFFFFFF007202AC0);
104 | ADDRESS(ml_phys_write_data) = SLIDE(0xFFFFFFF007202D20);
105 | ADDRESS(ml_io_map) = SLIDE(0xFFFFFFF0072084AC);
106 | ADDRESS(ldr_w0_x0__ret) = SLIDE(0xFFFFFFF00711F1D4);
107 | ADDRESS(str_w1_x0__ret) = SLIDE(0xFFFFFFF00711F280);
108 | ADDRESS(CpuDataEntries) = SLIDE(0xFFFFFFF0076ACD48);
109 | }
110 |
111 | static void
112 | parameters__iphone10_1__17B102() {
113 | gPhysBase = kernel_read64(SLIDE(0xFFFFFFF007906B68));
114 | gVirtBase = kernel_read64(SLIDE(0xFFFFFFF007906B70));
115 | rorgn_begin = kernel_read64(SLIDE(0xFFFFFFF007906E58));
116 | rorgn_end = kernel_read64(SLIDE(0xFFFFFFF007906E60));
117 | cpu_ttep = kernel_read64(SLIDE(0xFFFFFFF0079067C0));
118 | kernel_pmap = kernel_read64(SLIDE(0xFFFFFFF0079067A0));
119 | ADDRESS(pmap_find_phys) = SLIDE(0xFFFFFFF007CC39CC);
120 | ADDRESS(ml_phys_read_data) = SLIDE(0xFFFFFFF007CCFF0C);
121 | ADDRESS(ml_phys_write_data) = SLIDE(0xFFFFFFF007CD01B0);
122 | ADDRESS(ml_io_map) = SLIDE(0xFFFFFFF007CD5864);
123 | ADDRESS(ldr_w0_x0__ret) = SLIDE(0xFFFFFFF007BD2EFC);
124 | ADDRESS(str_w1_x0__ret) = SLIDE(0xFFFFFFF007BD2F80);
125 | ADDRESS(CpuDataEntries) = SLIDE(0xFFFFFFF0091CACB8);
126 | }
127 |
128 | static void
129 | parameters__iphone10_1__17C54() {
130 | gPhysBase = kernel_read64(SLIDE(0xFFFFFFF00790AB68));
131 | gVirtBase = kernel_read64(SLIDE(0xFFFFFFF00790AB70));
132 | rorgn_begin = kernel_read64(SLIDE(0xFFFFFFF00790AE58));
133 | rorgn_end = kernel_read64(SLIDE(0xFFFFFFF00790AE60));
134 | cpu_ttep = kernel_read64(SLIDE(0xFFFFFFF00790A7C0));
135 | kernel_pmap = kernel_read64(SLIDE(0xFFFFFFF00790A7A0));
136 | ADDRESS(pmap_find_phys) = SLIDE(0xFFFFFFF007CCBDAC);
137 | ADDRESS(ml_phys_read_data) = SLIDE(0xFFFFFFF007CD83EC);
138 | ADDRESS(ml_phys_write_data) = SLIDE(0xFFFFFFF007CD8690);
139 | ADDRESS(ml_io_map) = SLIDE(0xFFFFFFF007CDDD44);
140 | ADDRESS(ldr_w0_x0__ret) = SLIDE(0xFFFFFFF007BDAF34);
141 | ADDRESS(str_w1_x0__ret) = SLIDE(0xFFFFFFF007BDAFB8);
142 | ADDRESS(CpuDataEntries) = SLIDE(0xFFFFFFF0091D2C98);
143 | }
144 |
145 | static struct platform_initialization parameters[] = {
146 | { "iPhone10,1", "16C101", parameters__iphone10_1__16C101 },
147 | { "iPhone10,6", "16E227", parameters__iphone10_6__16E227 },
148 | { "iPhone10,1", "16G77", parameters__iphone10_1__16G77 },
149 | { "iPhone10,1|iPhone10,4", "17B102", parameters__iphone10_1__17B102 },
150 | { "iPhone10,1|iPhone10,4", "17C54", parameters__iphone10_1__17C54 },
151 | };
152 |
153 | // ---- Public API --------------------------------------------------------------------------------
154 |
155 | #define ARRAY_COUNT(x) (sizeof(x) / sizeof((x)[0]))
156 |
157 | bool
158 | ktrr_bypass_parameters_init() {
159 | static bool initialized = false;
160 | if (initialized) {
161 | return true;
162 | }
163 | assert(kernel_slide != 0);
164 | size_t count = run_platform_initializations(offsets, ARRAY_COUNT(offsets));
165 | if (count < 1) {
166 | ERROR("No KTRR bypass %s for %s %s", "offests",
167 | platform.machine, platform.osversion);
168 | return false;
169 | }
170 | count = run_platform_initializations(parameters, ARRAY_COUNT(parameters));
171 | if (count < 1) {
172 | ERROR("No KTRR bypass %s for %s %s", "parameters",
173 | platform.machine, platform.osversion);
174 | return false;
175 | }
176 | initialized = true;
177 | return true;
178 | }
179 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/ktrr/ktrr_bypass_parameters.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef KTRR_BYPASS_PARAMETERS__H_
21 | #define KTRR_BYPASS_PARAMETERS__H_
22 |
23 | #include "log.h"
24 | #include "parameters.h"
25 |
26 | #ifdef KTRR_BYPASS_PARAMETERS_EXTERN
27 | #define extern KTRR_BYPASS_PARAMETERS_EXTERN
28 | #endif
29 |
30 | extern uint64_t gPhysBase;
31 | extern uint64_t gVirtBase;
32 | extern uint64_t rorgn_begin;
33 | extern uint64_t rorgn_end;
34 | extern uint64_t cpu_ttep;
35 | extern uint64_t kernel_pmap;
36 | extern uint64_t ADDRESS(pmap_find_phys);
37 | extern uint64_t ADDRESS(ml_phys_read_data);
38 | extern uint64_t ADDRESS(ml_phys_write_data);
39 | extern uint64_t ADDRESS(ml_io_map);
40 | extern uint64_t ADDRESS(ldr_w0_x0__ret);
41 | extern uint64_t ADDRESS(str_w1_x0__ret);
42 | extern uint64_t ADDRESS(CpuDataEntries);
43 | extern size_t SIZE(cpu_data_entry);
44 | extern size_t OFFSET(cpu_data_entry, cpu_data_vaddr);
45 | extern size_t OFFSET(cpu_data, cpu_regmap_paddr);
46 | extern size_t OFFSET(cpu_data, ed_mmio);
47 | extern size_t OFFSET(cpu_data, utt_mmio);
48 |
49 | /*
50 | * ktrr_bypass_parameters_init
51 | *
52 | * Description:
53 | * Initialize the parameters used in the KTRR bypass.
54 | */
55 | bool ktrr_bypass_parameters_init(void);
56 |
57 | #undef extern
58 |
59 | #endif
60 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/ktrw_kext_loader.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | get-task-allow
6 |
7 | task_for_pid-allow
8 |
9 | platform-application
10 |
11 | com.apple.private.security.container-required
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/ktrw_kext_loader.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/ktrw_kext_loader.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/ktrw_kext_loader.xcodeproj/xcshareddata/xcschemes/ktrw_kext_loader.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/main.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "kernel_call.h"
4 | #include "kernel_memory.h"
5 | #include "kernel_patches.h"
6 | #include "kext_load.h"
7 | #include "ktrr_bypass.h"
8 | #include "log.h"
9 |
10 | int main(int argc, const char *argv[]) {
11 | int ret = 1;
12 | // Parse arguments.
13 | if (argc != 2) {
14 | printf("usage: %s \n", argv[0]);
15 | goto done_0;
16 | }
17 | const char *kext_path = argv[1];
18 | // Load the kernel symbol database.
19 | bool ok = kext_load_set_kernel_symbol_database("kernel_symbols");
20 | if (!ok) {
21 | ERROR("Could not load kernel symbol database");
22 | goto done_0;
23 | }
24 | // Try to get the kernel task port using task_for_pid().
25 | kernel_task_port = MACH_PORT_NULL;
26 | task_for_pid(mach_task_self(), 0, &kernel_task_port);
27 | if (kernel_task_port == MACH_PORT_NULL) {
28 | ERROR("Could not get kernel task port");
29 | goto done_0;
30 | }
31 | INFO("task_for_pid(0) = 0x%x", kernel_task_port);
32 | // Initialize our kernel function calling capability.
33 | ok = kernel_call_init();
34 | if (!ok) {
35 | ERROR("Could not initialize kernel_call subsystem");
36 | goto done_0;
37 | }
38 | // TODO: Check if we've already bypassed KTRR.
39 | // Ensure that we have a KTRR bypass.
40 | ok = have_ktrr_bypass();
41 | if (!ok) {
42 | ERROR("No KTRR bypass is available for this platform");
43 | goto done_1;
44 | }
45 | // Bypass KTRR and remap the kernel as read/write.
46 | ktrr_bypass();
47 | // Apply kernel patches.
48 | apply_kernel_patches();
49 | // Load the kernel extension.
50 | uint64_t kext_address = kext_load(kext_path, 171);
51 | if (kext_address == 0) {
52 | ERROR("Could not load kext %s", kext_path);
53 | goto done_1;
54 | }
55 | INFO("Kext %s loaded at address 0x%016llx", kext_path, kext_address);
56 | ret = 0;
57 | done_1:
58 | // De-initialize our kernel function calling primitive.
59 | kernel_call_deinit();
60 | done_0:
61 | return ret;
62 | }
63 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/system/bundle_path.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #include "bundle_path.h"
21 |
22 | #include
23 |
24 | void
25 | get_bundle_path(char *buffer, size_t size) {
26 | CFBundleRef bundle = CFBundleGetMainBundle();
27 | CFURLRef url = CFBundleCopyBundleURL(bundle);
28 | CFURLGetFileSystemRepresentation(url, true, (UInt8 *)buffer, size);
29 | CFRelease(url);
30 | }
31 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/system/bundle_path.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef BUNDLE_PATH__H_
21 | #define BUNDLE_PATH__H_
22 |
23 | #include
24 |
25 | /*
26 | * get_bundle_path
27 | *
28 | * Description:
29 | * Copy the absolute path to the bundle directory (without the trailing slash) into the
30 | * specified buffer.
31 | */
32 | void get_bundle_path(char *buffer, size_t size);
33 |
34 | #endif
35 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/system/log.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #include "log.h"
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | void
27 | log_internal(char type, const char *format, ...) {
28 | if (log_implementation != NULL) {
29 | va_list ap;
30 | va_start(ap, format);
31 | log_implementation(type, format, ap);
32 | va_end(ap);
33 | }
34 | }
35 |
36 | // The default logging implementation prints to stderr with a nice hacker prefix.
37 | static void
38 | log_stderr(char type, const char *format, va_list ap) {
39 | char *message = NULL;
40 | vasprintf(&message, format, ap);
41 | assert(message != NULL);
42 | switch (type) {
43 | case 'D': type = 'D'; break;
44 | case 'I': type = '+'; break;
45 | case 'W': type = '!'; break;
46 | case 'E': type = '-'; break;
47 | }
48 | fprintf(stderr, "[%c] %s\n", type, message);
49 | free(message);
50 | }
51 |
52 | void (*log_implementation)(char type, const char *format, va_list ap) = log_stderr;
53 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/system/log.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef LOG__H_
21 | #define LOG__H_
22 |
23 | #include
24 | #include
25 |
26 | /*
27 | * log_implementation
28 | *
29 | * Description:
30 | * This is the log handler that will be executed when code wants to log a message. The default
31 | * implementation logs the message to stderr. Setting this value to NULL will disable all
32 | * logging. Specify a custom log handler to process log messages in another way.
33 | *
34 | * Parameters:
35 | * type A character representing the type of message that is being
36 | * logged.
37 | * format A printf-style format string describing the error message.
38 | * ap The variadic argument list for the format string.
39 | *
40 | * Log Type:
41 | * The type parameter is one of:
42 | * - D: Debug: Used for debugging messages. Set the DEBUG build variable to control debug
43 | * verbosity.
44 | * - I: Info: Used to convey general information about the exploit or its progress.
45 | * - W: Warning: Used to indicate that an unusual but possibly recoverable condition was
46 | * encountered.
47 | * - E: Error: Used to indicate that an unrecoverable error was encountered. The code
48 | * might continue running after an error was encountered, but it probably will
49 | * not succeed.
50 | */
51 | extern void (*log_implementation)(char type, const char *format, va_list ap);
52 |
53 | #define DEBUG_LEVEL(level) (DEBUG && level <= DEBUG)
54 |
55 | #if DEBUG
56 | #define DEBUG_TRACE(level, fmt, ...) \
57 | do { \
58 | if (DEBUG_LEVEL(level)) { \
59 | log_internal('D', fmt, ##__VA_ARGS__); \
60 | } \
61 | } while (0)
62 | #else
63 | #define DEBUG_TRACE(level, fmt, ...) do {} while (0)
64 | #endif
65 | #define INFO(fmt, ...) log_internal('I', fmt, ##__VA_ARGS__)
66 | #define WARNING(fmt, ...) log_internal('W', fmt, ##__VA_ARGS__)
67 | #define ERROR(fmt, ...) log_internal('E', fmt, ##__VA_ARGS__)
68 |
69 | // A function to call the logging implementation.
70 | void log_internal(char type, const char *format, ...) __printflike(2, 3);
71 |
72 | #endif
73 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/system/map_file.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #include "map_file.h"
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 |
30 | #include "log.h"
31 |
32 |
33 | void *
34 | map_file(const char *path, size_t *size) {
35 | int fd = open(path, O_RDONLY);
36 | if (fd < 0) {
37 | ERROR("Could not open file \"%s\": %s", path, strerror(errno));
38 | return NULL;
39 | }
40 | struct stat st;
41 | int err = fstat(fd, &st);
42 | if (err != 0) {
43 | ERROR("Could not stat file \"%s\": %s", path, strerror(errno));
44 | close(fd);
45 | return NULL;
46 | }
47 | size_t file_size = st.st_size;
48 | void *data = mmap(NULL, file_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
49 | close(fd);
50 | if (data == MAP_FAILED) {
51 | ERROR("Could not map file \"%s\": %s", path, strerror(errno));
52 | return NULL;
53 | }
54 | *size = file_size;
55 | return data;
56 | }
57 |
58 | void
59 | unmap_file(void *data, size_t size) {
60 | munmap(data, size);
61 | }
62 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/system/map_file.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef MAP_FILE__H_
21 | #define MAP_FILE__H_
22 |
23 | #include
24 |
25 | /*
26 | * map_file
27 | *
28 | * Description:
29 | * Maps the specified file into memory. Returns the address and size of the mapping.
30 | */
31 | void *map_file(const char *path, size_t *size);
32 |
33 | /*
34 | * unmap_file
35 | *
36 | * Description:
37 | * Unmap a file mapped with map_file().
38 | */
39 | void unmap_file(void *data, size_t size);
40 |
41 | #endif
42 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/system/parameters.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef PARAMETERS__H_
21 | #define PARAMETERS__H_
22 |
23 | #include
24 | #include
25 | #include
26 |
27 | #include "platform.h"
28 |
29 | // Marks a parameter as a weak symbol, allowing multiple non-conflicting definitions.
30 | #define PARAMETER_SHARED __attribute__((weak))
31 |
32 | // Generate the name for an offset.
33 | #define OFFSET(base_, object_) _##base_##__##object_##__offset_
34 |
35 | // Generate the name for the size of an object.
36 | #define SIZE(object_) _##object_##__size_
37 |
38 | // Generate the name for the address of an object.
39 | #define ADDRESS(object_) _##object_##__address_
40 |
41 | // Generate the name for the static (unslid) address of an object.
42 | #define STATIC_ADDRESS(object_) _##object_##__static_address_
43 |
44 | // A structure describing the PAC codes used as part of the context for signing and verifying
45 | // virtual method pointers in a vtable.
46 | struct vtable_pac_codes {
47 | size_t count;
48 | const uint16_t *codes;
49 | };
50 |
51 | // Generate the name for an offset in a virtual method table.
52 | #define VTABLE_INDEX(class_, method_) _##class_##_##method_##__vtable_index_
53 |
54 | // Generate the name for a list of vtable PAC codes.
55 | #define VTABLE_PAC_CODES(class_) _##class_##__vtable_pac_codes_
56 |
57 | // A helper macro for INIT_VTABLE_PAC_CODES().
58 | #define VTABLE_PAC_CODES_DATA(class_) _##class_##__vtable_pac_codes_data_
59 |
60 | // Initialize a list of vtable PAC codes. In order to store the PAC code array in constant memory,
61 | // we place it in a static variable. Consequently, this macro will produce name conflicts if used
62 | // outside a function.
63 | #define INIT_VTABLE_PAC_CODES(class_, ...) \
64 | static const uint16_t VTABLE_PAC_CODES_DATA(class_)[] = { __VA_ARGS__ }; \
65 | VTABLE_PAC_CODES(class_) = (struct vtable_pac_codes) { \
66 | .count = sizeof(VTABLE_PAC_CODES_DATA(class_)) / sizeof(uint16_t), \
67 | .codes = (const uint16_t *) VTABLE_PAC_CODES_DATA(class_), \
68 | }
69 |
70 | // A convenience macro for accessing a field of a structure.
71 | #define FIELD(object_, struct_, field_, type_) \
72 | ( *(type_ *) ( ((uint8_t *) object_) + OFFSET(struct_, field_) ) )
73 |
74 | #endif
75 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/system/platform.c:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #define PLATFORM_EXTERN
21 | #include "platform.h"
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | #include "log.h"
29 |
30 | // ---- Initialization ----------------------------------------------------------------------------
31 |
32 | void
33 | platform_init() {
34 | // Only initialize once.
35 | static bool initialized = false;
36 | if (initialized) {
37 | return;
38 | }
39 | initialized = true;
40 | // Set the page size.
41 | platform.page_size = vm_kernel_page_size;
42 | page_size = platform.page_size;
43 | // Get the machine name (e.g. iPhone11,8).
44 | struct utsname u = {};
45 | int error = uname(&u);
46 | assert(error == 0);
47 | strncpy((char *)platform.machine, u.machine, sizeof(platform.machine));
48 | // Get the build (e.g. 16C50).
49 | size_t osversion_size = sizeof(platform.osversion);
50 | error = sysctlbyname("kern.osversion",
51 | (void *)platform.osversion, &osversion_size, NULL, 0);
52 | assert(error == 0);
53 | // Get basic host info.
54 | mach_port_t host = mach_host_self();
55 | assert(MACH_PORT_VALID(host));
56 | host_basic_info_data_t basic_info;
57 | mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
58 | kern_return_t kr = host_info(host, HOST_BASIC_INFO, (host_info_t) &basic_info, &count);
59 | assert(kr == KERN_SUCCESS);
60 | platform.cpu_type = basic_info.cpu_type;
61 | platform.cpu_subtype = basic_info.cpu_subtype;
62 | platform.physical_cpu = basic_info.physical_cpu;
63 | platform.logical_cpu = basic_info.logical_cpu;
64 | platform.memory_size = basic_info.max_mem;
65 | mach_port_deallocate(mach_task_self(), host);
66 | // Log basic platform info.
67 | INFO("Platform: %s %s", platform.machine, platform.osversion);
68 | }
69 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/system/platform.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef PLATFORM__H_
21 | #define PLATFORM__H_
22 |
23 | #include
24 | #include
25 | #include
26 |
27 | #ifdef PLATFORM_EXTERN
28 | #define extern PLATFORM_EXTERN
29 | #endif
30 |
31 | /*
32 | * platform
33 | *
34 | * Description:
35 | * Basic information about the platform.
36 | */
37 | struct platform {
38 | // The name of the platform, e.g. iPhone11,8.
39 | const char machine[32];
40 | // The version of the OS build, e.g. 16C50.
41 | const char osversion[32];
42 | // The platform CPU type.
43 | cpu_type_t cpu_type;
44 | // The platform CPU subtype.
45 | cpu_subtype_t cpu_subtype;
46 | // The number of physical CPU cores.
47 | unsigned physical_cpu;
48 | // The number of logical CPU cores.
49 | unsigned logical_cpu;
50 | // The kernel page size.
51 | size_t page_size;
52 | // The size of physical memory on the device.
53 | size_t memory_size;
54 | };
55 | extern struct platform platform;
56 |
57 | /*
58 | * page_size
59 | *
60 | * Description:
61 | * The kernel page size on this platform, made available globally for convenience.
62 | */
63 | extern size_t page_size;
64 |
65 | /*
66 | * platform_init
67 | *
68 | * Description:
69 | * Initialize the platform.
70 | */
71 | void platform_init(void);
72 |
73 | #undef extern
74 |
75 | #endif
76 |
--------------------------------------------------------------------------------
/ktrw_kext_loader/system/platform_match.h:
--------------------------------------------------------------------------------
1 | //
2 | // Project: KTRW
3 | // Author: Brandon Azad
4 | //
5 | // Copyright 2019 Google LLC
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #ifndef PLATFORM_MATCH__H_
21 | #define PLATFORM_MATCH__H_
22 |
23 | #include
24 | #include
25 |
26 | /*
27 | * platform_matches_device
28 | *
29 | * Description:
30 | * Check whether the current platform matches the specified device or range of devices.
31 | *
32 | * Match format:
33 | * The match string may either specify a single device glob or a range of device globs. For
34 | * example:
35 | *
36 | * "iPhone11,8" Matches only iPhone11,8
37 | * "iPhone11,*" Matches all iPhone11 devices, including e.g. iPhone11,4.
38 | * "iPhone*,*" Matches all iPhone devices.
39 | * "iPhone11,4-iPhone11,8" Matches all iPhone devices between 11,4 and 11,8, inclusive.
40 | * "iPhone10,*-11,*" Matches all iPhone10 and iPhone11 devices.
41 | * "iPhon10,1|iPhone10,6" Matches iPhone10,1 and iPhone10,6.
42 | * "*", NULL Matches all devices.
43 | */
44 | bool platform_matches_device(const char *device_range);
45 |
46 | /*
47 | * platform_matches_build
48 | *
49 | * Description:
50 | * Check whether the current platform matches the specified build version or range of build
51 | * versions.
52 | *
53 | * Match format:
54 | * The match string may either specify a single build version or a range of build versions.
55 | * For example:
56 | *
57 | * "16C50" Matches only build 16C50.
58 | * "16B92-16C50" Matches all builds between 16B92 and 16C50, inclusive.
59 | *
60 | * As a special case, either build version may be replaced with "*" to indicate a lack of
61 | * lower or upper bound:
62 | *
63 | * "*-16B92" Matches all builds up to and including 16B92.
64 | * "16C50-*" Matches build 16C50 and later.
65 | * "*", NULL Matches all build versions.
66 | */
67 | bool platform_matches_build(const char *build_range);
68 |
69 | /*
70 | * platform_matches
71 | *
72 | * Description:
73 | * A convenience function that combines platform_matches_device() and
74 | * platform_matches_build().
75 | */
76 | bool platform_matches(const char *device_range, const char *build_range);
77 |
78 | // A struct describing an initialization for a particular set of devices and builds.
79 | struct platform_initialization {
80 | const char *devices;
81 | const char *builds;
82 | void (*init)(void);
83 | };
84 |
85 | /*
86 | * run_platform_initializations
87 | *
88 | * Description:
89 | * Run each of the platform initializations that match the current device and build.
90 | *
91 | * Returns the number of initializations that ran.
92 | */
93 | size_t run_platform_initializations(struct platform_initialization *inits, size_t count);
94 |
95 | #endif
96 |
--------------------------------------------------------------------------------
/ktrw_usb_proxy/Makefile:
--------------------------------------------------------------------------------
1 | TARGET = ktrw_usb_proxy
2 |
3 | DEBUG ?= 0
4 |
5 | CFLAGS = -O2 -Wall -Werror
6 |
7 | ifneq ($(DEBUG),0)
8 | CFLAGS += -DDEBUG=$(DEBUG)
9 | endif
10 |
11 | SOURCES = source/ktrw_usb_proxy.c
12 |
13 | HEADERS =
14 |
15 | FRAMEWORKS = -framework IOKit -framework CoreFoundation
16 |
17 | $(TARGET): $(SOURCES) $(HEADERS)
18 | $(CC) $(CFLAGS) $(DEFINES) $(LDFLAGS) $(FRAMEWORKS) -o $@ $(SOURCES)
19 |
20 | clean:
21 | rm -f -- $(TARGET)
22 |
--------------------------------------------------------------------------------
/misc/dbg_xnu.cfg.patch:
--------------------------------------------------------------------------------
1 | --- dbg_xnu.cfg.orig
2 | +++ dbg_xnu.cfg
3 | @@ -270,6 +270,66 @@
4 | "com.corellium.gdb.arm64.state":
5 | {
6 | "title": "FP/Exception State Registers"
7 | + },
8 | + "com.apple.debugserver.arm64.general":
9 | + {
10 | + "title": "General Registers",
11 | + "rename":
12 | + {
13 | + "cpsr": "psr",
14 | + "fp": "x29",
15 | + "lr": "x30"
16 | + },
17 | + "stack_ptr": "sp",
18 | + "code_ptr": "pc",
19 | + "frame_ptr": "x29",
20 | + "data_ptr":
21 | + [
22 | + "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
23 | + "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
24 | + "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
25 | + "x24", "x25", "x26", "x27", "x28", "x29", "x30"
26 | + ],
27 | + "bitfields":
28 | + {
29 | + "psr":
30 | + {
31 | + "M": [ 0, 4 ],
32 | + "F": [ 6, 6 ],
33 | + "I": [ 7, 7 ],
34 | + "A": [ 8, 8 ],
35 | + "D": [ 9, 9 ],
36 | + "IL": [ 20, 20 ],
37 | + "SS": [ 21, 21 ],
38 | + "PAN": [ 22, 22 ],
39 | + "UAO": [ 23, 23 ],
40 | + "DIT": [ 24, 24 ],
41 | + "V": [ 28, 28 ],
42 | + "C": [ 29, 29 ],
43 | + "Z": [ 30, 30 ],
44 | + "N": [ 31, 31 ]
45 | + }
46 | + }
47 | + },
48 | + "com.apple.debugserver.arm64.low":
49 | + {
50 | + "title": "General Registers (32-bit)"
51 | + },
52 | + "com.apple.debugserver.arm64.single":
53 | + {
54 | + "title": "Floating Point Registers (Single Precision)"
55 | + },
56 | + "com.apple.debugserver.arm64.double":
57 | + {
58 | + "title": "Floating Point Registers (Double Precision)"
59 | + },
60 | + "com.apple.debugserver.arm64.neon":
61 | + {
62 | + "title": "NEON Registers"
63 | + },
64 | + "com.apple.debugserver.arm64.state":
65 | + {
66 | + "title": "FP/Exception State Registers"
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/pongo_kext_loader/Makefile:
--------------------------------------------------------------------------------
1 | TARGET = pongo_kext_loader
2 |
3 | DEBUG ?= 0
4 |
5 | CFLAGS = -O2 -Wall -Werror
6 |
7 | ifneq ($(DEBUG),0)
8 | CFLAGS += -DDEBUG=$(DEBUG)
9 | endif
10 |
11 | SOURCES = source/pongo_kext_loader.c
12 |
13 | HEADERS =
14 |
15 | FRAMEWORKS = -framework IOKit -framework CoreFoundation
16 |
17 | $(TARGET): $(SOURCES) $(HEADERS)
18 | $(CC) $(CFLAGS) $(DEFINES) $(LDFLAGS) $(FRAMEWORKS) -o $@ $(SOURCES)
19 |
20 | clean:
21 | rm -f -- $(TARGET)
22 |
--------------------------------------------------------------------------------
/pongo_kextload/Makefile:
--------------------------------------------------------------------------------
1 | TARGET = kextload.pongo-module
2 |
3 | ARCH = arm64
4 | SDK = iphoneos
5 | ABI = aapcs
6 |
7 | SYSROOT := $(shell xcrun --sdk $(SDK) --show-sdk-path)
8 | ifeq ($(SYSROOT),)
9 | $(error Could not find SDK $(SDK))
10 | endif
11 | CLANG := $(shell xcrun --sdk $(SDK) --find clang)
12 | CC := $(CLANG) -isysroot $(SYSROOT) -arch $(ARCH)
13 |
14 | CFLAGS = -mabi=$(ABI) -fno-builtin -fno-common -mkernel
15 | CFLAGS += -Isource/third_party
16 | CFLAGS += -O2
17 | CFLAGS += -Wall -Werror -Wpedantic -Wno-gnu -Wno-language-extension-token -Wconversion
18 |
19 | LDFLAGS = -Xlinker -kext -nostdlib -Xlinker -fatal_warnings
20 |
21 | SOURCES = source/pongo_kextload.c
22 |
23 | HEADERS = source/third_party/pongo.h
24 |
25 | $(TARGET): $(SOURCES) $(HEADERS)
26 | $(CC) $(CFLAGS) $(DEFINES) $(LDFLAGS) -o $@ $(SOURCES)
27 |
28 | symbols: $(TARGET)
29 | @nm -u $(TARGET)
30 |
31 | clean:
32 | rm -rf -- $(TARGET).$(ARCH).ld
33 | rm -f -- $(TARGET)
34 |
--------------------------------------------------------------------------------