Can Ghidra re-compile and run a short function? - c

I've picked out a short and "self-contained" function from the Ghidra decompiler. Can Ghidra itself compile the function again so I can try to run it for a couple different values, or would I need to compile it myself with e.g. gcc?
Attaching the function for context:
undefined8 FUN_140041010(char *param_1,longlong param_2,uint param_3)
{
char *pcVar1;
uint uVar2;
ulonglong uVar3;
uVar3 = 0;
if (param_3 != 0) {
pcVar1 = param_1;
do {
if (pcVar1[param_2 - (longlong)param_1] == '\0') {
if ((uint)uVar3 < param_3) {
param_1[uVar3] = '\0';
return 0;
}
break;
}
*pcVar1 = pcVar1[param_2 - (longlong)param_1];
uVar2 = (uint)uVar3 + 1;
uVar3 = (ulonglong)uVar2;
pcVar1 = pcVar1 + 1;
} while (uVar2 < param_3);
}
param_1[param_3 - 1] = '\0';
return 0;
}

Can Ghidra itself compile the function again so I can try to run it for a couple different values
The P-Code emulator of Ghidra is intended for this kind of scenario.
If it is just a short function and doesn't use other libraries, syscalls, etc like your example then the emulator can easily handle this without further effort on your side to emulate library functions. Ghidra knows the semantics of each instruction and converts them to the standardized P-Code format for e.g. decompilation, but this can also be combined with a "P-Code virtual machine".
It will most likely still involve a bit of scripting, though there exist plugins like TheRomanXpl0it/ghidra-emu-fun to make this easier. There are also more general tutorials if you want to understand the basic idea and usage of the Emulator API (which is not exposed in the GUI in any way)
If you run into issues while scripting the emulator I would recommend asking specific questions about the emulator API at the dedicated Reverse Engineering Stack Exchange

You can, but you'll have to change some of the types to be standard C, or just add typedefs like so:
#include <stdint.h>
typedef uint8_t undefined8;
typedef long long int longlong;
typedef unsigned long long int ulonglong;
typedef unsigned int uint;
undefined8 FUN_140041010(char *param_1,longlong param_2,uint param_3)
{
char *pcVar1;
uint uVar2;
ulonglong uVar3;
uVar3 = 0;
if (param_3 != 0) {
pcVar1 = param_1;
do {
if (pcVar1[param_2 - (longlong)param_1] == '\0') {
if ((uint)uVar3 < param_3) {
param_1[uVar3] = '\0';
return 0;
}
break;
}
*pcVar1 = pcVar1[param_2 - (longlong)param_1];
uVar2 = (uint)uVar3 + 1;
uVar3 = (ulonglong)uVar2;
pcVar1 = pcVar1 + 1;
} while (uVar2 < param_3);
}
param_1[param_3 - 1] = '\0';
return 0;
}
Then you can call it like any function:
int main(int argc, char const* argv[])
{
char* mystr = "hello";
printf("%hhu\n", FUN_140041010(mystr, /* not sure about this arg */ 0, strlen(mystr));
return 0;
}

Related

Excel Add-in: Assignment in for loop causes segmentation fault but line-by-line assignments work. Why?

I just tested a toy Excel add-in project, cross building the XLL with mingw32 tool chains.
Here is my code:
//testXLL.c
#include "windows.h"
#include "xlcall.h"
#define MEMORYSIZE 65535000
char vMemBlock[MEMORYSIZE];
int vOffsetMemBlock =0;
LPSTR GetTempMemory(int cBytes){
LPSTR lpMemory;
if(vOffsetMemBlock + cBytes > MEMORYSIZE)
return 0;
else{
lpMemory = (LPSTR) &vMemBlock + vOffsetMemBlock;
vOffsetMemBlock += cBytes;
if(vOffsetMemBlock & 1) vOffsetMemBlock++;
return lpMemory;
}
}
LPXLOPER TempStr(LPSTR lpstr){
LPXLOPER lpx;
int chars;
lpx = (LPXLOPER)GetTempMemory(sizeof(XLOPER));
if(!lpx) return 0;
chars = lstrlen(lpstr);
if(chars>255) chars=255;
lpx->val.str=(char*)GetTempMemory((sizeof(char)*chars+1));
if(!lpx->val.str) return 0;
strncpy(lpx->val.str, lpstr,chars);
lpx->val.str[0]=(BYTE) chars;
//lpx->val.str[chars]='\0';
lpx->xltype = xltypeStr;
return lpx;
}
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) double __stdcall myadd2(double a1,double a2){
return a1+a2;
}
static char functionTable[11][255] =
{" myadd2", // procedure
" BBB", // type_text
" add", // function_text
" add1,add2", // argument_text
" 1", // macro_type
" category", // category
" ", // shortcut_text
" some help topic", // help_topic
" Adds toy", // function_help
" 1st.", // argument_help1
" 2nd" // argument_help2
};
__declspec(dllexport) int __stdcall xlAutoOpen(){
LPXLOPER pxDLL;
Excel4(xlGetName,pxDLL,0);
XLOPER xlRegArgs[11];
for(int i = 0; i < 11; i++){
xlRegArgs[i] = *TempStr(functionTable[i]);
}
Excel4(xlfRegister, 0, 12,
pxDLL,
&xlRegArgs[0], &xlRegArgs[1], &xlRegArgs[2],
&xlRegArgs[3], &xlRegArgs[4], &xlRegArgs[5],
&xlRegArgs[6], &xlRegArgs[7], &xlRegArgs[8],
&xlRegArgs[9], &xlRegArgs[10]);
return 1;
}
__declspec(dllexport) LPXLOPER __stdcall xlAddInManagerInfo(LPXLOPER xlAction) {
static XLOPER xlReturn, xlLongName, xlTemp;
xlTemp.xltype = xltypeInt;
xlTemp.val.w = xltypeInt;
Excel4(xlCoerce, &xlReturn, 2, xlAction, &xlTemp);
if(1 == xlReturn.val.w) {
xlLongName = *TempStr(" xll-name");
} else {
xlLongName.xltype = xltypeErr;
xlLongName.val.err = xlerrValue;
}
return &xlLongName;
}
#ifdef __cplusplus
}
#endif
I built this testXLL.c file in Ubuntu:
>i686-w64-mingw32-gcc -shared -Wl,--kill-at testXLL.c -o win.xll -L. -lxlcall32
This generates the "win.xll" successfully but, when loading this win.xll, Excel crashes.
In Windows 10, I tried to use gdb to debug it, but I can't catch break point in the xll file – it got disabled automatically when loading. But I can see in the gdb output, it is a segmentation fault when Excel crashes.
XLOPER xlRegArgs[11];
for(int i = 0; i < 11; i++){
xlRegArgs[i] = *TempStr(functionTable[i]);
}
What's weird is that, if I substitute the above for loop with the following line-by-line assignments in the xlAutoOpen function, the compiled XLL file works fine in Excel:
XLOPER xlRegArgs[11];
xlRegArgs[0] = *TempStr(functionTable[0]);
xlRegArgs[1] = *TempStr(functionTable[1]);
xlRegArgs[2] = *TempStr(functionTable[2]);
xlRegArgs[3] = *TempStr(functionTable[3]);
xlRegArgs[4] = *TempStr(functionTable[4]);
xlRegArgs[5] = *TempStr(functionTable[5]);
xlRegArgs[6] = *TempStr(functionTable[6]);
xlRegArgs[7] = *TempStr(functionTable[7]);
xlRegArgs[8] = *TempStr(functionTable[8]);
xlRegArgs[9] = *TempStr(functionTable[9]);
xlRegArgs[10] = *TempStr(functionTable[10]);
Please enlighten me. What's the difference between these two assignment approaches?
Although I don't (yet) have a full explanation for this behaviour, I'm posting this as a possible 'workaround', which I have used in a very similar case I encountered in one of my projects.
The issue appears to be some form of 'stack corruption' caused by the use of the function-local variable (i) used as the loop index; converting this to a global/static variable will likely fix the issue. The following code snippet is a suggested fix (I have changed the name of the index variable to avoid possible name clashes elsewhere in the code):
///...
static int regloop; // Used as the loop index, below...
__declspec(dllexport) int __stdcall xlAutoOpen(){
LPXLOPER pxDLL;
Excel4(xlGetName,pxDLL,0);
XLOPER xlRegArgs[11];
for(regloop = 0; regloop < 11; regloop++){
xlRegArgs[regloop] = *TempStr(functionTable[regloop]);
}
Here's the section of code from my aforementioned project (but note this is C++/MFC) that exhibits the same sort of behaviour – but only in x86 builds (x64 builds work without issue):
static int plin; // NOTA BENE:- We use this in the two functions below, as the use of
// a local 'plin' loop index is prone to induce stack corruption (?),
// especially in MSVC 2017 (MFC 14) builds for x86.
void BasicApp::OnUpdatePICmd(uint32_t nID, void *pUI)
{
//! for (int plin = 0; plin < Plugin_Number; ++plin) { // Can cause problems - vide supra
for (plin = 0; plin < Plugin_Number; ++plin) {
BOOL mEbl = FALSE; int mChk = -1;
if ((Plugin_UDCfnc[plin] != nullptr) && Plugin_UDCfnc[plin](nID, &mEbl, &mChk)) {
CommandEnable(pUI, mEbl ? true : false);
if (mChk >= 0) CmdUISetCheck(pUI, mChk);
return;
}
}
CommandEnable(pUI, false);
return;
}
(The Plugin_UDCfnc is a static array member of the BasicApp class.)
I have, in the years since the above code was written, had occasional 'fleeting insights' into why this is happening but, as of now, I can't offer a more robust fix. I shall revisit the issue and update this post if I should stumble upon a resolution. In the meantime, others are welcome to take this as a 'clue' and post their own explanations/solutions.

Identify User Defined Function and Library Defined Function

I'm given a task to write a program that checks a piece of code, maximum of 20 lines of code, when the program runs you type in a function name, number of lines of code and type in the codes.
It's meant to search in the code and return if the function name you entered is a Library Function or User Defined Function or No Function if it doesn't find it, the code I've written is below, it doesn't work because I made mistakes and I've been trying to fix it but can't seem to figure it out, and I tried debugging to see where I made mistake, and I figured that in the function SearchRealisation it returns an error that
Run-Time Check Failure #2 - Stack around the variable 'buff' was
corrupted.
This program sample returns Library function instead of user defined function
type the function name: addition
Get count string in code: 9
int addition(int num1, int num2)
{
int result = num1 + num2; //trial
return result;
}
int main()
{
addition(8, 9);
}
Output is Library Function but correct output should be User Defined Function since it was defined in the code
void InputText(int length, char Text[MAX_STRINGS][MAX_COLUMNS])
{
//Repeat by Count String
gets_s(Text[0]);
for (int i = 0; i < length; i++)
gets_s(Text[i]);
//Output a string (starting with � zero and ending with Count String-1)
}
void OutMesseg(int param)
{
//Display one of three messages according to the parameter
if (param == -2)
printf("%s", "user defined function");
else if (param == -1)
printf("%s", "no function");
else
printf("%s", "library function");
}
char* DeleteComentsInString(char Text[MAX_STRINGS], char New[MAX_STRINGS])
{
char* a = strstr(Text, "//");
int len = strlen(Text);
if (a != NULL) len -= strlen(a);
strncpy(New, Text, len);
New[len] = '\0';
return New;
}
bool IsTypeC(char Word[MAX_STRINGS])
{
char ctype[6][MAX_STRINGS] =
{
"int",
"bool",
"char",
"float",
"double",
"void"
};
for (int i = 0; i < 6; i++)
{
if (strstr(Word, ctype[i]) != 0)
return true;
}
return false;
}
int SearchRealisation(int length, char Text[MAX_STRINGS][MAX_COLUMNS], int index_fanc, int& end)
{
int count = 0;
int start = -1;
end = -1;
char buff[MAX_STRINGS];
//Find first {
for (int i = index_fanc + 1; i < length && !count; i++)
{
if (strstr(DeleteComentsInString(Text[i], buff), "{") != NULL)
{
count++;
start = i;
}
}
//find last }
for (int i = start + 1; i < length && count; i++)
{
if (strstr(DeleteComentsInString(Text[i], buff), "{") != NULL)
count++;
else if (strstr(DeleteComentsInString(Text[i], buff), "}") != NULL)
count--;
if (!count)
end = i;
}
if (end == -1)
start = -1;
else
return start;
}
int SearchFunction(int length, char Text[MAX_STRINGS][MAX_COLUMNS], char FunctionName[MAX_COLUMNS], int& end)
{
//bool flag = false;
char commentDel[120];
int in;
for (int i = 0; i < length; ++i)
{
DeleteComentsInString(Text[i], commentDel);
if (strstr(commentDel, FunctionName) != NULL)
{
in = strlen(commentDel) - strlen(strstr(commentDel, FunctionName));
if ((in == 0 || (in != 0 && commentDel[in - 1] == ' ')) && (commentDel[in + strlen(FunctionName)] == ' ' || commentDel[in + strlen(FunctionName)] == '(') && strstr(commentDel, ";") == NULL)
{
return SearchRealisation(length, Text, i, end);
}
}
}
end = -1;
return -1;
}
int SearchResult(int length, char Text[MAX_STRINGS][MAX_COLUMNS], char FunctionName[MAX_COLUMNS])
{
int index;
int end;
int start = SearchFunction(length, Text, FunctionName, end);
if (start == -1)
return -1;
index = SearchFunction(length, Text, FunctionName, end);
if (index < 0)
return -2;
return index;
}
int findFunction(char string[MAX_STRINGS][MAX_COLUMNS], char* functName, int M)
{
return 0;
}
int main()
{
int length = 0;
char Code[MAX_STRINGS][MAX_COLUMNS] = { 0 };
char FunctionName[MAX_COLUMNS];
//char ConstantName[MAX_STRINGS];
printf("type the function name: ");
scanf("%s", &FunctionName);
printf("Get count string in code: ");
scanf("%d", &length);
InputText(length, Code);
printf("\n");
OutMesseg(SearchResult(length, Code, FunctionName));
return 0;
}
Well, you have been given a very difficult task:
There's no way to check this, as functions are resolved by a dynamic process that depends on your filesystem state, which is not available at runtime, after you have already compiled your program.
How do you distinguish a function that is compiled in a separate (but user defined) compilation unit from a system defined function? (e.g. double log(double);) that is defined in a math library? There is no way: the linker gets both from a different place (in the first case it gets it from the place you compiled the separate module, in the system case it gets it from a common library directory that has all the system related functions), but you don't have that information available at runtime).
In order to do this task feasible, you'd at least have the full set of source code files of your program. Preprocess them with the cpp(1) preprocessor (so you bypass all the macro expansion invocations) and then check for all function calls in the source code that are not provided in the full set of sources you have. This is quite similar to what the linker does. After compilation, the compiler leaves an object file with the compiled code, and a symbol table that identifies all the unresolved identifiers, and more important all the provided identifiers from this module. The linker then goes on all your modules trying to solve the unknowns, and for each that it doesn't have a solution in your code, it goes to the library directory to search for it. If it doesn't find it in either one, it fails telling you something is wrong.
In my opinion, you have been given a trap task, as the C language preprocess its input (this is something you should do, as many functions are hidden in the internals of macro bodies), then parse the code (for this, you need to write a C parser, which is no trivial task) to select which identifiers are defined in your code and which aren't. Finally you need to check all the calls you do in the code to divide the set in two groups, calls that are defined (and implemented) in your code, and calls that aren't (implemented, all the calls the compiler needs must be defined with some kind of prototype).
It's my opinion, but you have not a simple task, solvable in a short program (of perhaps one hundred lines) but a huge one.
Thanks a lot to everyone that answered I came up with a way to search the code for function definition and thereby return a value if its defined or not, or not even found, might not be the best solution to the task but works so far

C programming byte data type

I am doing a ctf and I have reversed and elf file and found the function that encodes the flag and i have made a decoder but because it is in c i cant use the byte data type. Is there any library that i can add and if not how did this code use the byte data type. I alredy did some challanges by this author and i solved the by deocidng the in c, and i think that this is something called dynamic string traformation.
// the original encoder
undefined8 main(void)
{
int iVar1;
ssize_t sVar2;
long in_FS_OFFSET;
int local_40;
byte local_38 [40];
long local_10;
local_10 = *(long *)(in_FS_OFFSET + 0x28);
initialize_flag();
puts("Give me your password: ");
sVar2 = read(0,local_38,0x1f);
local_38[(int)sVar2 + -1] = 0;
local_40 = 0x28;
while (local_40 < (int)sVar2 + -1) {
local_38[local_40] = local_38[local_40] ^ (char)local_40 + 10U;
local_38[local_40] = local_38[local_40] - 2;
local_40 = local_40 + 1;
}
iVar1 = strcmp((char *)local_38,"lp`7a<qLw\x1ekHopt(f-f*,o}V\x0f\x15J");
if (iVar1 == 0) {
puts("Thats the right password!");
printf("Flag: %s",flagBuffer);
}
else {
puts("Thats not the password!");
}
if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return 0;
}
Here is my encoder:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
ssize_t sVar2;
int local_40;
byte local_38 [40];
sVar2 = read(0,local_38,0x1f);
local_38[(int)sVar2 + -1] = 0;
local_40 = 27;// the flag lenght is 27
while (local_40 > 0) {
//this is the reverse of the og encoding
local_40 = local_40 - 1;
local_38[local_40] = local_38[local_40] - 2;
local_38[local_40] = (local_38[local_40] ^ (char)local_40) - 10U;
}
puts(local_38);
return 0;
}
//lp`7a<qLw\x1ekHopt(f-f*,o}V\x0f\x15J this is the encoded flag
// s after the original encoding should be w
The comments already have gotten you two great answers(Using stdint.h or chars), but otherwise...
If you do not have access to the stdint header and do not want to use chars, libraries such as Boost can provide you the uint8_t datatype, too.
In C++, you have std::byte accessible(Not sure you, specifically, will be helped by that, but others maybe)
If you wish to make sure a char is 8-bits of lenght, you can check the CHAR_BIT value defined in .
So your options(Ranking from best to worse) are:
(If you can use cpp) Using std::byte
Using the uint8_t datatype defined in <stdint.h>
Using a char/unsigned char
Using an external library
Note it's probably overkill using an external library for such a trivial task unless you already have that said library.
Hope this helps.
your decoder seems to have some errors like: local_38[local_40] = local_38[local_40] - 2;
It should be like this: local_38[local_40] = local_38[local_40] + 2;
I have written a decoder for above question in python
key="lp`7a<qLw\x1ekHopt(f-f*,o}V\x0f\x15J"
check=list(key)
string=str()
string=''
for i in range(26,-1,-1):
j=i+10
k=(ord(check[i])+2)
string=(chr(k^j)+string)
print(string)
Hope this will help

How to generate Universally Unique IDentifier, UUID from LoadRunner independent of the OS

I have experienced the need of generating UUID in LoadRunner several times while scripting but there is no in-build function to do so. I am using both linux and windows load generators.
Thanks to Scott Moore for writing the below code which uses windows in-build CoCreateGuid function (dependent on ole32.dll) to generate required UUID. However that code is completely dependent on windows platform and doesn't work in Linux platform.
How can we generate UUID from Loadrunner independent of OS?
#include "lrun.h"
#include "web_api.h"
#include "lrw_custom_body.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"
int lr_guid_gen()
{
typedef struct _GUID
{
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[8];
} GUID;
GUID m_guid;
char buf[50];
lr_load_dll ("ole32.dll");
CoCreateGuid(&m_guid);
sprintf (buf, "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
m_guid.Data1, m_guid.Data2, m_guid.Data3,
m_guid.Data4[0], m_guid.Data4[1], m_guid.Data4[2], m_guid.Data4[3],
m_guid.Data4[4], m_guid.Data4[5], m_guid.Data4[6], m_guid.Data4[7]);
lr_save_string(buf, "PAR_GUID");
return 0;
}
You can use the following trick which doesn't require any code.
Define a hex parameter as follows:
Then use it with this code:
lr_eval_string("{MyHex}{MyHex}-{MyHex}-{MyHex}-{MyHex}-{MyHex}{MyHex}{MyHex}")
I have come up with the below mentioned solution
int lr_guid_gen()
{
char GUID[40];
int t = 0;
char *szTemp = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
char *szHex = "0123456789abcdef-";
int nLen = strlen (szTemp);
for (t=0; t<nLen+1; t++)
{
int r = rand () % 16;
char c = ' ';
switch (szTemp[t])
{
case 'x' : { c = szHex [r]; } break;
case 'y' : { c = szHex [r & 0x03 | 0x08]; } break;
case '-' : { c = '-'; } break;
case '4' : { c = '4'; } break;
}
GUID[t] = ( t < nLen ) ? c : 0x00;
}
lr_save_string(GUID,"PAR_GUID");
return 0;
}

How mbtowc uses locale?

I have hard time using mbtowc, which keeps returning wrong results. It also puzzles me why the function even uses locale? Multibyte unicode chars points are locale independent. I implemented custom conversion function that convert it well, see the code below.
I use GCC 4.8.1 on Windows (where sizeof wchar_t is 2), using Czech locale (cs_CZ). The OEM codepage is windows-1250, console by default uses CP852. These are my results so far:
#include <stdio.h>
#include <stdlib.h>
// my custom conversion function
int u8toint(const char* str) {
if(!(*str&128)) return *str;
unsigned char c = *str, bytes = 0;
while((c<<=1)&128) ++bytes;
int result = 0;
for(int i=bytes; i>0; --i) result|= (*(str+i)&127)<<(6*(bytes-i));
int mask = 1;
for(int i=bytes; i<6; ++i) mask<<= 1, mask|= 1;
result|= (*str&mask)<<(6*bytes);
return result;
}
// data inspecting type for the tests in main()
union data {
wchar_t w;
struct {
unsigned char b1, b2;
} bytes;
} a,b,c;
int main() {
// I tried setlocale here
mbtowc(NULL, 0, 0); // reset internal mb_state
mbtowc(&(a.w),"ř",6); // apply mbtowc
b.w = u8toint("ř"); // apply custom function
c.w = L'ř'; // compare to wchar
printf("\na = %hhx%hhx", a.bytes.b2, a.bytes.b1); // a = 0c5 wrong
printf("\nb = %hhx%hhx", b.bytes.b2, b.bytes.b1); // b = 159 right
printf("\nc = %hhx%hhx", c.bytes.b2, c.bytes.b1); // c = 159 right
getchar();
}
Here are setlocale settings and the results for a:
setlocale(LC_CTYPE,"Czech_Czech Republic.1250"); // a = 139 wrong
setlocale(LC_CTYPE,"Czech_Czech Republic.852"); // a = 253c wrong
Why mbtowc doesn't give 0x159 - the unicode number of ř?

Resources