1+ /* Locate magic and extract table from compiled binaries */
2+ #include "utils.h"
3+ #include <acpi.h>
4+ #include <common.h>
5+ #include <stdio.h>
6+ #include <stdlib.h>
7+ #include <string.h>
8+
9+ int main (int argc , char * * argv ) {
10+ uint32_t table_size = 0 ;
11+ uint32_t table_start_offset = 0 ;
12+ ACPI_TABLE_HEADER * table_header = NULL ;
13+ char * output_file_path = NULL ;
14+ FileContent output_table = {0 };
15+ FileContent input_binary = {0 };
16+
17+ int ret = 0 ;
18+
19+ // Check args, one for input binary, one for output acpi table
20+ if (argc != 3 && argc != 2 ) {
21+ log_warn ("Usage: %s <tz.mbn/hyp.mbn> <output path>" , argv [0 ]);
22+ return - EINVAL ;
23+ }
24+
25+ // Open input binary file
26+ input_binary .filePath = argv [1 ];
27+
28+ // Read buffer from input binary
29+ if (!get_file_size (& input_binary )) {
30+ log_err ("Failed to get file size for %s" , input_binary .filePath );
31+ return - EINVAL ;
32+ }
33+ input_binary .fileBuffer = malloc (input_binary .fileSize );
34+ read_file_content (& input_binary );
35+
36+ // Locate magic in input binary
37+ char table_start_magic [] = {'2' , 'K' , 'D' , 'E' , 'M' , 'O' , 'C' , 'Q' };
38+ for (size_t i = 0x10 ; i < input_binary .fileSize - sizeof (table_start_magic );
39+ i ++ ) {
40+ if (memcmp (input_binary .fileBuffer + i , table_start_magic ,
41+ sizeof (table_start_magic )) == 0 ) {
42+ table_start_offset = i - 0x10 ; // Adjust to table header start
43+ }
44+ }
45+
46+ // Check if table found
47+ if (table_start_offset == 0 ) {
48+ free (input_binary .fileBuffer );
49+ log_err ("Table start magic not found in %s" , input_binary .filePath );
50+ return - ENOENT ;
51+ }
52+
53+ // Map header
54+ table_header =
55+ (ACPI_TABLE_HEADER * )(input_binary .fileBuffer + table_start_offset );
56+
57+ // Calulate and validate table size
58+ table_size = table_header -> Length ;
59+ if (table_size <= 0 ||
60+ table_size > input_binary .fileSize - table_start_offset ) {
61+ printf ("[WARN] Invalid table size %u\n" , table_size );
62+ }
63+
64+ // Calculate and correct checksum
65+ table_header -> Checksum =
66+ checksum (input_binary .fileBuffer + table_start_offset , table_size );
67+
68+ // Check if output file string does not exist
69+ if (argc == 2 ) {
70+ // Write file to current directory with default file name from input binary
71+ char table_name [5 ];
72+ memcpy (table_name , table_header -> Signature , 4 );
73+ table_name [4 ] = '\0' ;
74+
75+ size_t out_len = sizeof (table_name ) + 4 ; // Signature.aml + '\0'
76+ output_file_path = malloc (out_len );
77+ if (!output_file_path ) {
78+ free (input_binary .fileBuffer );
79+ log_err ("Failed to allocate memory for output file path" );
80+ return - ENOMEM ;
81+ }
82+ // Construct output file path
83+ snprintf (output_file_path , out_len , "%s.%s" , table_name , "aml" );
84+ output_table .filePath = output_file_path ;
85+ } else if (argc >= 3 && is_directory (argv [2 ])) {
86+ // Output to specified directory with default file name from input binary
87+ char table_name [5 ];
88+ memcpy (table_name , table_header -> Signature , 4 );
89+ table_name [4 ] = '\0' ;
90+ size_t out_len =
91+ strlen (argv [2 ]) + sizeof (table_name ) + 5 ; // dir/Signature.aml + '\0'
92+ output_file_path = malloc (out_len );
93+ if (!output_file_path ) {
94+ free (input_binary .fileBuffer );
95+ log_err ("Failed to allocate memory for output file path" );
96+ return - ENOMEM ;
97+ }
98+ // Remove the last '/' if exists
99+ if (argv [2 ][strlen (argv [2 ]) - 1 ] == '/' )
100+ argv [2 ][strlen (argv [2 ]) - 1 ] = '\0' ;
101+ // Construct output file path
102+ snprintf (output_file_path , out_len , "%s/%s.%s" , argv [2 ], table_name , "aml" );
103+ output_table .filePath = output_file_path ;
104+ } else {
105+ output_table .filePath = argv [2 ];
106+ }
107+
108+ // Write table to output file
109+ output_table .fileSize = table_size ;
110+ output_table .fileBuffer = malloc (output_table .fileSize );
111+ memcpy (output_table .fileBuffer , input_binary .fileBuffer + table_start_offset ,
112+ output_table .fileSize );
113+ ret = write_file_content (& output_table );
114+ if (ret < 0 ) {
115+ log_err ("Failed to write ACPI table to %s" , output_table .filePath );
116+ free (input_binary .fileBuffer );
117+ free (output_table .fileBuffer );
118+ if (output_file_path )
119+ free (output_file_path );
120+ return ret ;
121+ }
122+
123+ // Success
124+ log_info ("Table %c%c%c%c extracted to :\t%s" , table_header -> Signature [0 ],
125+ table_header -> Signature [1 ], table_header -> Signature [2 ],
126+ table_header -> Signature [3 ], output_table .filePath );
127+
128+ // Clean up
129+ free (input_binary .fileBuffer );
130+ free (output_table .fileBuffer );
131+ if (output_file_path )
132+ free (output_file_path );
133+
134+ return ret ;
135+ }
0 commit comments