question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

C Parser Does Not Parse A Simple Struct

See original GitHub issue

Describe the bug I tried recently to parse certain data structures from the XNU kernel. I encountered a simple struct that could not be parsed.

The struct is defined in a XNU header file. All data types are of type __uint32_t which is a typedef for unsigned int.

Interestingly, the parsing works if the type in the struct definition is changed to unsigned int. Therefore, I guess the parser cannot parse the type definition for some reason.

More interestingly, the parser recognizes the the __uint32_t as valid.

I tried this with 9.0.4 and 9.1-BETA.

Lines mentioned in the screenshot:

#line 35: "<redacted>/xnu-4903.241.1/osfmk/mach/arm/_structs.h"


struct arm_exception_state
{
	__uint32_t	exception; 
	__uint32_t	fsr; 
	__uint32_t	far; 
};

To Reproduce Steps to reproduce the behavior:

  1. Create an empty parser profile
  2. Add the following configuration
-I<redacted>/xnu-4903.241.1/osfmk/
-I<redacted>/xnu-4903.241.1/libkern/
-I<redacted>/xnu-4903.241.1/iokit/
-I<redacted>/xnu-4903.241.1/bsd/
-I<redacted>/xnu-4903.241.1/EXTERNAL_HEADERS/
-D__arm64__
-DKERNEL=1
-DIOKIT
-D__GNUC__
  1. Parse the following header from XNU: xnu-4903.241.1/osfmk/mach/arm/_structs.h 3.1. You need to download the whole XNU tree from https://opensource.apple.com/tarballs/xnu/xnu-4903.241.1.tar.gz
  2. Try to parse.

Expected behavior The header is parsed and added to the data type library.

Screenshots parsing_test

Environment (please complete the following information):

  • OS: Linux
  • Java Version: OpenJDK 11
  • Ghidra Version: 9.0.4 and 9.1-BETA

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:8 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
mgmchenrycommented, Dec 16, 2020

I would rate the CParserPlugin as nearly unusable. I was trying to generate headers for lua 5.3.5 and found whether I used VS or gcc for standard includes, it could not parse seemingly quite basic ifdef/end pairs (this is documented in other open issues for CParserPlugin)

I did find a workaround. I created a custom header file that when parsed with gcc generates a pre-parsed header file that ghidra can consume successfully.

gcc -E -dU -P -I".\src" -o luaTypes.gcc-E-dU.parsed.5.3.5.h luaTypes.gcc-E-dD.5.3.5.h

Creating the custom header file is a little like porting to a new platform. I eliminated as many dependencies and unneeded attributes with strategic defines: #undef __stdcall #undef __cdecl #undef _stdcall #undef _cdecl

#define __stdcall #define __cdecl #define _stdcall #define _cdecl

typedef void * va_list; /* platform independnt va_list / #define va_list / to suppress va_list definition in stdarg.h / #define __GNUC_VA_LIST / to suppress __gnuc_va_list in stdarg.h / #define _GCC_MAX_ALIGN_T / to suppress max_align_t in stddef.h / #define _INC__MINGW_H / to suppress __debugbreak and __mingw_get_crt_info in _mingw.h / /#define _INC_CRTDEFS*/ #define __MINGW_EXTENSION #define _CRT_ERRNO_DEFINED #define _ERRCODE_DEFINED #define _INC_STDDEF

#include <stdarg.h> #undef GNUC /* undefine GNUC after stdarg.h to prevent problematic defines in llimits.h and luaconf.h / / but must remain defined before stdarg.h is parsed */ #define _CRTIMP #define _INC_STDIO

#define LUA_COMPAT_5_2

#include “lprefix.h” #include “lua.h” #include “lapi.h” etc, etc, finally processing the target header files

This was a giant pain, but I was able to produce a type archive with exactly what I needed in it.

0reactions
raymontagcommented, Oct 8, 2019

@0x6d696368 Thx, that sounds like a neat workaround!

Read more comments on GitHub >

github_iconTop Results From Across the Web

parsing into a struct - Stack Overflow
Your primary problem in readNode() is your declaration of Node *node = NULL; declares a pointer that is initialized NULL and points to...
Read more >
Modelling C Structs And Typedefs At Parse Time - Blog
We'll review the simple and almost correct version first, and then explore the subtle (and rather serious) case where it is not correct: ......
Read more >
nom_derive::Nom - Rust - Docs.rs
Deriving parsers supports struct and enum types. Many examples are provided ... Default, fields, Do not parse, set a field to the default...
Read more >
libcurl example - xmlstream.c
xmlstream.c ... This software is licensed as described in the file COPYING, ... (struct ParserStruct *) XML_GetUserData(parser); /* Only parse if we are...
Read more >
Type System and Tools for the RPC Programming Assignment
A C++ parsing framework that creates a tree of C++ objects corresponding to ... When this declaration is encountered, the IDL parser will...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found