@@ -87,12 +87,17 @@ static ut64 lua_parse_line_defined(LuaProto *proto, RzBuffer *buffer, ut64 offse
8787 size_offset = lua_parse_number (buffer , & line_defined , offset , data_size , minor );
8888 lua_check_error_offset (size_offset );
8989
90+ /* Set Proto Member */
91+ proto -> line_defined = (ut64 )line_defined ;
92+
93+ if (minor == 0 ) {
94+ return size_offset ;
95+ }
96+
9097 const ut64 delta_offset = lua_parse_number (buffer , & last_line_defined , offset + size_offset , data_size , minor );
9198 lua_check_error_offset (delta_offset );
9299 size_offset += delta_offset ;
93100
94- /* Set Proto Member */
95- proto -> line_defined = (ut64 )line_defined ;
96101 proto -> lastline_defined = (ut64 )last_line_defined ;
97102 return size_offset ;
98103}
@@ -161,7 +166,7 @@ static ut64 lua_parse_string(RzBuffer *buffer, ut8 **dest, int *str_len, ut64 of
161166 RZ_LOG_ERROR ("Cannot store string\n" );
162167 }
163168
164- if ((minor == 2 ) || (minor == 5 ))
169+ if ((( minor == 0 ) && ( ret_buf_size > 0 )) || ( minor == 2 ) || (minor == 5 ))
165170 offset ++ ;
166171 return offset - base_offset ;
167172}
@@ -181,15 +186,15 @@ static ut64 lua_parse_code(LuaProto *proto, RzBuffer *buffer, ut64 offset, ut64
181186 ut64 aligned_size = (offset + 3 ) & ~3 ;
182187 size_offset = aligned_size - offset ;
183188 }
184-
185- ut64 total_size = code_size * 4 + size_offset ;
189+ ut8 instruction_size = ( minor == 0 ) ? 8 : 4 ;
190+ ut64 total_size = code_size * instruction_size + size_offset ;
186191 if (total_size + offset > data_size ) {
187192 RZ_LOG_ERROR ("Truncated Code at [0x%llx]\n" , offset );
188193 return 0 ;
189194 }
190195
191196 /* Set Proto Member */
192- proto -> code_size = code_size * 4 ;
197+ proto -> code_size = code_size * instruction_size ;
193198 proto -> code_skipped = size_offset ;
194199 return total_size ;
195200}
@@ -227,7 +232,7 @@ static ut64 lua_parse_const_entry(const LuaProto *proto, RzBuffer *buffer, ut64
227232 current_entry -> tag = LUA_VNUMFLT ; // keep the same with 5.4 tag
228233 break ;
229234 }
230- if ((minor == 1 ) || (minor == 2 )) {
235+ if ((minor == 0 ) || ( minor == 1 ) || (minor == 2 )) {
231236 double intPart1 ;
232237 double r = * (double * )recv_data ;
233238 double fractionalPart = modf (r , & intPart1 );
@@ -511,7 +516,7 @@ LuaProto *lua_parse_body(RzBuffer *buffer, LuaHeaderInfo *header, ut64 base_offs
511516 /* record offset of main proto */
512517 ret_proto -> offset = offset ;
513518
514- if ((minor == 1 ) || (minor == 3 ) || (minor == 4 )) {
519+ if ((minor == 0 ) || ( minor == 1 ) || (minor == 3 ) || (minor == 4 )) {
515520 /* parse proto name of main proto */
516521 delta_offset = lua_parse_name (ret_proto , buffer , offset , data_size , minor );
517522 if (minor == 1 ) {
@@ -531,6 +536,17 @@ LuaProto *lua_parse_body(RzBuffer *buffer, LuaHeaderInfo *header, ut64 base_offs
531536 if ((minor == 1 ) && (ret_proto -> line_defined > 0 ))
532537 offset ++ ;
533538
539+ if (minor == 0 ) {
540+ int size_upvalues = 0 ;
541+ ut8 tmp ;
542+ if (!rz_buf_read8_at (buffer , offset , & tmp )) {
543+ return 0 ;
544+ }
545+ offset ++ ;
546+ size_upvalues = tmp ;
547+ (void )size_upvalues ;
548+ }
549+
534550 /* parse num params max_stack_size */
535551 if (offset + 3 > data_size ) {
536552 lua_free_proto_entry (ret_proto );
@@ -545,19 +561,47 @@ LuaProto *lua_parse_body(RzBuffer *buffer, LuaHeaderInfo *header, ut64 base_offs
545561 }
546562 offset += 3 ;
547563
564+ if (minor == 0 ) {
565+ /* parse debug */
566+ ret_proto -> debug_offset = offset ;
567+ delta_offset = lua_parse_debug (ret_proto , buffer , offset , data_size , minor );
568+ lua_check_error_offset_proto (delta_offset , ret_proto );
569+ offset += delta_offset ;
570+
571+ /* parse constants */
572+ ret_proto -> const_offset = offset ;
573+ delta_offset = lua_parse_consts (ret_proto , buffer , offset , data_size , minor );
574+ lua_check_error_offset_proto (delta_offset , ret_proto );
575+ offset += delta_offset ;
576+
577+ /* parse inner protos */
578+ ret_proto -> inner_proto_offset = offset ;
579+ delta_offset = lua_parse_protos (ret_proto , buffer , header , offset , data_size );
580+ lua_check_error_offset_proto (delta_offset , ret_proto );
581+ offset += delta_offset ;
582+
583+ /* specially handle recursive protos size */
584+ ret_proto -> inner_proto_size = offset - ret_proto -> inner_proto_offset ;
585+ }
586+
548587 /* parse code */
549588 ret_proto -> code_offset = offset ;
550589 delta_offset = lua_parse_code (ret_proto , buffer , offset , data_size , minor );
551590 lua_check_error_offset_proto (delta_offset , ret_proto );
552591 offset += delta_offset ;
553592
593+ if (minor == 0 ) {
594+ ret_proto -> size = offset - base_offset + 1 ;
595+ return ret_proto ;
596+ }
597+
554598 /* parse constants */
555599 ret_proto -> const_offset = offset ;
556600 delta_offset = lua_parse_consts (ret_proto , buffer , offset , data_size , minor );
557601 lua_check_error_offset_proto (delta_offset , ret_proto );
558602 offset += delta_offset ;
559603
560- if (minor <= 2 ) {
604+ if (( minor == 1 ) || ( minor == 2 ) ) {
561605 /* parse inner protos */
562606 ret_proto -> inner_proto_offset = offset ;
563607 delta_offset = lua_parse_protos (ret_proto , buffer , header , offset , data_size );
@@ -641,7 +685,7 @@ size_t parse_header(const RzBinFile *bf, LuaHeaderInfo *header) {
641685 return 0 ;
642686 }
643687
644- if (minor < 1 || minor > 5 ) {
688+ if (minor > 5 ) {
645689 RZ_LOG_ERROR ("lua 5.%c not support now\n" , header -> minor + '0' );
646690 return 0 ;
647691 }
@@ -650,12 +694,16 @@ size_t parse_header(const RzBinFile *bf, LuaHeaderInfo *header) {
650694 CHECK_SIZE ;
651695
652696 /* read header members from work buffer */
653- if (!rz_buf_read8_at (buffer , offset , & header -> format )) {
654- return 0 ;
697+ /* is official compiler (minor > 0) */
698+ if (minor > 0 ) {
699+ if (!rz_buf_read8_at (buffer , offset , & header -> format )) {
700+ return 0 ;
701+ }
702+ offset ++ ;
703+ CHECK_SIZE ;
655704 }
656- offset ++ ;
657- CHECK_SIZE ;
658705
706+ /* check luac data if minor > 2 */
659707 if (minor > 2 ) {
660708 offset += strlen (LUAC_DATA );
661709 } else {
@@ -670,19 +718,18 @@ size_t parse_header(const RzBinFile *bf, LuaHeaderInfo *header) {
670718 /* get int size on 5.1, 5.2, 5.3, 5.5 */
671719 if (minor == 5 ) {
672720 const ut64 size_offset = lua_parse_szint (buffer , & header -> int_size , offset , bf -> size , minor );
673- // printf("size_offset: %llu, offset: %llu\n", size_offset, offset);
674721 offset += size_offset ;
675722 CHECK_SIZE ;
676723 const ut32 test_valid = lua_load_int (buffer , offset );
677724 (void )test_valid ;
678725 offset += header -> int_size ;
679- // printf("offset: %llu, int_size: %x, test_valid: %x\n\n", offset, int_size, test_valid);
680726 } else if (minor <= 3 ) { ///< TODO: ????? need 3?
681727 ut8 tmp ;
682728 if (!rz_buf_read8_at (buffer , offset , & tmp )) {
683729 return 0 ;
684730 }
685731 header -> int_size = tmp ;
732+ header -> integer_size = 4 ;
686733 offset ++ ;
687734 } else {
688735 header -> int_size = 4 ;
@@ -724,6 +771,46 @@ size_t parse_header(const RzBinFile *bf, LuaHeaderInfo *header) {
724771 CHECK_SIZE ;
725772 }
726773
774+ if (minor == 0 ) {
775+ ut8 tmp ;
776+ if (!rz_buf_read8_at (buffer , offset , & tmp )) {
777+ return 0 ;
778+ }
779+ offset ++ ;
780+ if (tmp != 6 ) {
781+ RZ_LOG_ERROR ("Wrong size of SIZE_OP\n" );
782+ return 0 ;
783+ }
784+ CHECK_SIZE ;
785+ if (!rz_buf_read8_at (buffer , offset , & tmp )) {
786+ return 0 ;
787+ }
788+ offset ++ ;
789+ if (tmp != 8 ) {
790+ RZ_LOG_ERROR ("Wrong size of SIZE_A\n" );
791+ return 0 ;
792+ }
793+ CHECK_SIZE ;
794+ if (!rz_buf_read8_at (buffer , offset , & tmp )) {
795+ return 0 ;
796+ }
797+ offset ++ ;
798+ if (tmp != 9 ) {
799+ RZ_LOG_ERROR ("Wrong size of SIZE_B\n" );
800+ return 0 ;
801+ }
802+ CHECK_SIZE ;
803+ if (!rz_buf_read8_at (buffer , offset , & tmp )) {
804+ return 0 ;
805+ }
806+ offset ++ ;
807+ if (tmp != 9 ) {
808+ RZ_LOG_ERROR ("Wrong size of SIZE_C\n" );
809+ return 0 ;
810+ }
811+ CHECK_SIZE ;
812+ }
813+
727814 /* get lua integer size on luac > 5.3 */
728815 if (minor == 5 ) {
729816 const ut64 size_offset = lua_parse_szint (buffer , & header -> integer_size , offset , bf -> size , minor );
@@ -772,6 +859,15 @@ size_t parse_header(const RzBinFile *bf, LuaHeaderInfo *header) {
772859 CHECK_SIZE ;
773860 header -> number_size = tmp ;
774861 }
862+ if (minor == 0 ) {
863+ double number_valid = lua_load_number (buffer , offset );
864+ if (number_valid != LUAC0_NUMBER_VALIDATION ) {
865+ RZ_LOG_ERROR ("Number format does not match with the expected number (expected: %f, actual: %f)\n" , LUAC0_NUMBER_VALIDATION , number_valid );
866+ return 0 ;
867+ }
868+ offset += header -> number_size ;
869+ CHECK_SIZE ;
870+ }
775871
776872 /* check lua number is integral on 5.1, 5.2 */
777873 if ((minor == 1 ) || (minor == 2 )) {
@@ -860,11 +956,19 @@ RzBinInfo *lua_parse_bin_info(const RzBinFile *bf, const LuaHeaderInfo *header)
860956
861957 /* Check Size */
862958 // TODO : remove this check and process different compiler options
863- if ((header -> instruction_size != sizeof (LUA_INSTRUCTION )) ||
864- (header -> integer_size != sizeof (LUA_INTEGER )) ||
865- (header -> number_size != sizeof (LUA_NUMBER ))) {
866- RZ_LOG_ERROR ("Size definition does not match with the expected size\n" );
867- return ret ;
959+ if (header -> minor == 0 ) {
960+ if ((header -> instruction_size != sizeof (ut64 )) ||
961+ (header -> number_size != sizeof (LUA_NUMBER ))) {
962+ RZ_LOG_ERROR ("Size definition does not match with the expected size (minor = 0)\n" );
963+ return ret ;
964+ }
965+ } else {
966+ if ((header -> instruction_size != sizeof (LUA_INSTRUCTION )) ||
967+ (header -> integer_size != sizeof (LUA_INTEGER )) ||
968+ (header -> number_size != sizeof (LUA_NUMBER ))) {
969+ RZ_LOG_ERROR ("Size definition does not match with the expected size\n" );
970+ return ret ;
971+ }
868972 }
869973
870974 if (header -> minor < 4 ) {
0 commit comments