OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
nvramdump.c
Go to the documentation of this file.
1//
2// main.c
3// NVRAMdump
4//
5// Created by Rodion Shingarev on 27.12.20.
6// Copyright © 2020 Rodion Shingarev. All rights reserved.
7// based on the original NVRAM utility
8// Copyright (c) 2000-2016 Apple Inc. All rights reserved.
9// https://opensource.apple.com/source/system_cmds/system_cmds-854.40.2/nvram.tproj/nvram.c
10//
11
12#include <stdio.h>
13
14#ifdef __APPLE__
15
16#include <stdlib.h>
17#include <IOKit/IOKitLib.h>
18#include <IOKit/IOKitKeys.h>
19#include <CoreFoundation/CoreFoundation.h>
20#include <err.h>
21#include <mach/mach_error.h>
22#include <string.h>
23
24static io_registry_entry_t gOptionsRef;
25
26// GetOFVariable(name, nameRef, valueRef)
27//
28// Get the named firmware variable.
29// Return it and its symbol in valueRef and nameRef.
30//
31static kern_return_t GetOFVariable(char *name, CFStringRef *nameRef,
32 CFTypeRef *valueRef)
33{
34 *nameRef = CFStringCreateWithCString(kCFAllocatorDefault, name,
35 kCFStringEncodingUTF8);
36 if (*nameRef == 0) {
37 errx(1, "Error creating CFString for key %s", name);
38 }
39
40 *valueRef = IORegistryEntryCreateCFProperty(gOptionsRef, *nameRef, 0, 0);
41 if (*valueRef == 0) return kIOReturnNotFound;
42
43 if (CFGetTypeID(*valueRef) == CFStringGetTypeID()) {
44 CFTypeRef oldValue = *valueRef;
45 *valueRef = CFStringCreateExternalRepresentation(kCFAllocatorDefault, *valueRef, kCFStringEncodingUTF8, 0);
46 CFRelease(oldValue);
47 if (*valueRef == 0) return kIOReturnNotFound;
48 }
49
50 return KERN_SUCCESS;
51}
52
53static CFMutableDictionaryRef dict4;
54
55static void ConvertStringValues (const void* key, const void* value, void* context) {
56 if (CFGetTypeID(value) == CFStringGetTypeID()) {
57 CFDataRef dataValue = CFStringCreateExternalRepresentation(kCFAllocatorDefault, value, kCFStringEncodingUTF8, 0);
58 if (dataValue != NULL) {
59 CFDictionaryAddValue(dict4, key, dataValue);
60 }
61 } else {
62 CFDictionaryAddValue(dict4, key, value);
63 }
64}
65
66
67CFDictionaryRef CreateMyDictionary(void) {
68 char *guid;
69
70 // root
71 CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
72 &kCFTypeDictionaryKeyCallBacks,
73 &kCFTypeDictionaryValueCallBacks);
74 //version
75 int version = 1;
76 CFNumberRef num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &version);
77 CFDictionarySetValue(dict, CFSTR("Version"), num);
78 CFRelease(num);
79 //Add
80 CFMutableDictionaryRef dict0 = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
81 &kCFTypeDictionaryValueCallBacks);
82 CFDictionarySetValue(dict, CFSTR("Add"), dict0);
83 CFRelease(dict0);
84
85 // APPLE_BOOT_VARIABLE_GUID
86 // Print all of the firmware variables.
87 CFMutableDictionaryRef dict1;
88 kern_return_t result;
89 result = IORegistryEntryCreateCFProperties(gOptionsRef, &dict1, 0, 0);
90 if (result != KERN_SUCCESS) {
91 errx(1, "Error getting the firmware variables: %s", mach_error_string(result));
92 }
93
94 // To work round limitations of OpenCore XML parser (i.e. XML entities not
95 // automatically processed), force all string values to save as data.
96 dict4 = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
97 &kCFTypeDictionaryKeyCallBacks,
98 &kCFTypeDictionaryValueCallBacks);
99 CFDictionaryApplyFunction(dict1, ConvertStringValues, NULL);
100
101 CFDictionarySetValue(dict0, CFSTR("7C436110-AB2A-4BBB-A880-FE41995C9F82"), dict4);
102 CFRelease(dict1);
103 CFRelease(dict4);
104
105 CFMutableDictionaryRef dict2 = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
106 &kCFTypeDictionaryValueCallBacks);
107 CFDictionarySetValue(dict0, CFSTR("8BE4DF61-93CA-11D2-AA0D-00E098032B8C"), dict2);
108
109 // EFI_GLOBAL_VARIABLE_GUID
110 // Print the given firmware variable.
111 CFStringRef nameRef;
112 CFTypeRef valueRef;
113
114 const char *key[32];
115 char name[64];
116 CFStringRef var;
117 int i = 0;
118 int n = 7; // num of keys in this GUID
119
120 key[0] = "Boot0080";
121 key[1] = "BootOrder";
122 key[2] = "BootNext";
123 key[3] = "Boot0081";
124 key[4] = "Boot0082";
125 key[5] = "Boot0083";
126 key[6] = "BootCurrent";
127 guid = "8BE4DF61-93CA-11D2-AA0D-00E098032B8C";
128
129 for ( i = 0; i < n; i++ ) {
130 snprintf(name, sizeof(name), "%s:%s", guid, key[i]);
131 var = CFStringCreateWithCString(NULL, key[i], kCFStringEncodingUTF8);
132 result = GetOFVariable(name, &nameRef, &valueRef);
133 if (result == KERN_SUCCESS) {
134 CFDictionaryAddValue (dict2, var, valueRef);
135 CFRelease(valueRef);
136 }
137 CFRelease(nameRef);
138 }
139 CFRelease(dict2);
140
141 // APPLE_WIRELESS_NETWORK_VARIABLE_GUID
142 CFMutableDictionaryRef dict3 = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks,
143 &kCFTypeDictionaryValueCallBacks);
144 CFDictionarySetValue(dict0, CFSTR("36C28AB5-6566-4C50-9EBD-CBB920F83843"), dict3);
145 n = 3; // num of keys in this GUID
146 key[0] = "current-network";
147 key[1] = "preferred-count";
148 key[2] = "preferred-networks";
149 guid = "36C28AB5-6566-4C50-9EBD-CBB920F83843";
150
151 for ( i = 0; i < n; i++ ) {
152 snprintf(name, sizeof(name), "%s:%s", guid, key[i]);
153 var = CFStringCreateWithCString(NULL, key[i], kCFStringEncodingUTF8);
154 result = GetOFVariable(name, &nameRef, &valueRef);
155 if (result == KERN_SUCCESS) {
156 CFDictionaryAddValue (dict3, var, valueRef);
157 CFRelease(valueRef);
158 }
159 CFRelease(nameRef);
160 }
161 CFRelease(dict3);
162
163 return dict;
164}
165
166int main(int argc, const char * argv[]) {
167 CFDataRef data;
168 FILE *fp;
169 kern_return_t result;
170 mach_port_t masterPort;
171
172 result = IOMasterPort(bootstrap_port, &masterPort);
173 if (result != KERN_SUCCESS) {
174 errx(1, "Error getting the IOMaster port: %s",
175 mach_error_string(result));
176 }
177
178 gOptionsRef = IORegistryEntryFromPath(masterPort, "IODeviceTree:/options");
179 if (gOptionsRef == 0) {
180 errx(1, "nvram is not supported on this system");
181 }
182 CFPropertyListRef propertyList = CreateMyDictionary();
183 data = CFPropertyListCreateData( kCFAllocatorDefault, propertyList, kCFPropertyListXMLFormat_v1_0, 0, NULL );
184 if (data == NULL) {
185 errx(1, "Error converting variables to xml");
186 }
187 fp = fopen ("/tmp/nvram.plist", "w");
188 if (fp == NULL) {
189 errx(1, "Error opening /tmp/nvram.plist");
190 }
191 fwrite(CFDataGetBytePtr(data), sizeof(UInt8), CFDataGetLength(data), fp);
192 fclose (fp);
193 CFRelease(data);
194 IOObjectRelease(gOptionsRef);
195 return 0;
196}
197
198#else
199
200int main() {
201 fprintf(stderr, "This utility is only supported on macOS\n");
202 return 1;
203}
204
205#endif
UINT8 version
Definition BmfFile.h:126
UINT8 value
#define snprintf
Definition Ubsan.h:205
int main()
Definition nvramdump.c:200