I'm just starting to get into reverse engineering and I came across a video by live overflow showcasing string format exploits using printf. I tried to reproduce his results but with no luck. My code is the same as in his video. I used radare2 to find the address of my target variable.
video: https://www.youtube.com/watch?v=0WvrSfcdq1I
radare2 output:
radare2 command prompt output
myCode:
#include <iostream>
using namespace std;
int overwritten;
void vuln(char *sdf) {
printf("typed stuff! -> ");
printf(sdf);
if(overwritten) {
printf("\nyou overwrote the var!");
}
}
int main(int argc, char *argv[]) {
vuln(argv[1]);
}
The part I'm having trouble with is at 7:54 in his video. He runs the program with a python script printing 'AAAA' + the variable address + 'bbbb' + '%x ' * 200. The output in his video is the variable's address surrounded by 41414141 and 42424242. This is the output I observe-> output. Why don't I even see the 41s and 42s?
Related
This is my first time using Ghidra and debugging. My project deals with reverse engineering a Dos executable from 2007, to understand how it generates a code.
I looked for the strings I can read when launching the program through wine (debugging under linux) and found one place :
/* Reverses the string */
__strrev(local_8);
local_4 = 0;
DISPLAY_MESSAGE(s__Code_=_%s_0040704c);
with DISPLAY_MESSAGE being :
int __cdecl DISPLAY_MESSAGE(byte *param_1)
{
int iVar1;
int errorCode;
iVar1 = FUN_004019c0((undefined4 *)&DAT_004072e8);
errorCode = FUN_00401ac0((char **)&DAT_004072e8,param_1,(undefined4 *)&stack0x00000008);
FUN_00401a60(iVar1,(int *)&DAT_004072e8);
return errorCode;
}
I named the function "DISPLAY_MESSAGE" because I saw the string on the screen ;-). I would like to name it printf but its signature does not match the one of printf since it takes byte * instead of char *, ... as input parameters and returns an int instead of void for the actual printf.
The string "Code = %s" (stripping the CRs and new lines) is actually located at address "0040704c", and I am very surprised not to see the variable holding the generated code value instead (that could help me rename the variables).
If I change the signature to the one of printf it yields :
DISPLAY_MESSAGE(s__Code_=_%s_0040704c,local_8)
which looks better, because local_8 could be the code, but I don't know if it is correct to change the signature like this (since then the local variable that I renamed errorCode is never used whereas it was returned before signature change).
void __cdecl DISPLAY_MESSAGE(char *param_1,...)
{
int iVar1;
int errorCode;
iVar1 = FUN_004019c0((undefined4 *)&DAT_004072e8);
FUN_00401ac0((char **)&DAT_004072e8,(byte *)param_1,(undefined4 *)&stack0x00000008);
FUN_00401a60(iVar1,(int *)&DAT_004072e8);
return;
}
So my questions are :
Why is Ghidra appending _0040704c to the string (should it help me, and how should I make use of this piece of info) ?
If my signature change is correct, what prevents Ghidra from finding the correct signature from its analysis ?
Should I think there is a problem with the function signature whenever I see undefinedX as it appears in DISPLAY_MESSAGE ?
Any help greatly appreciated!
I've got a new challenge to return the factorial of a number. Got ideas on how to do this, but the challenger has given some starting code - which is shown below.
Now this isn't how I would have started it (with my extremely limited experience!) - BUT I wasn't sure how system would grab some text & place within an int array - hence I tried running it within codeblocks, debugging and looking at the watch table. However I can't see 'num'.
So I tried copying num to num1:
int num1[30] = {0};
memset(num1[0],num[0], sizeof(num));
that doesn't seem to affect anything...
So question really is - is there something wrong with my codeblocks config (it debugs other programs and I've tried both cygwin & MiniGW) or is there another reason for this behavious?
#include <stdio.h>
#include <string.h>
void FirstFactorial(int num[]) {
// code goes here
printf("%d", num);
}
int main(void) {
// keep this function call here
FirstFactorial(gets(stdin));
return 0;
}
So I wrote this function in C using sscanf:
int parse_charstar(char *pointah)
{
int numbeh;
int retaahn = sscanf(pointah,"%*[^0123456789]%d",&numbeh);
printf("\n prent deeh numbeeh %d \n",numbeh);
return numbeh;
}
I want to get a number out of a string if there, for eg.
"hello 121"
number: 121
Currently using the above I'm getting garbage values, can someone help?
EDIT:
So I found something interesting today. Apparently, this is what was happening!
My code was never wrong to begin with as pointed out by luoluo and dasblinkenlight.
Problem was how I was calling the program. I'm on linux.
I was calling it as:
parse_charstar("1000");
Output:
prent deeh numbeeh -1634553883
I tried:
parse_charstar(" 1000 "); // added spaces
Output?
prent deeh numbeeh 1000
Spot on.
Now can someone tell me why this happens?
EDIT!!!
Hell with it guys, use strtol , its made for this stuff.
http://www.cplusplus.com/reference/cstdlib/strtol/
Code copied shamelessly from the above page:
#include <stdio.h> /* printf */
#include <stdlib.h> /* strtol */
int main ()
{
char szNumbers[] = "2001 60c0c0 -1101110100110100100000 0x6fffff";
char * pEnd;
long int li1, li2, li3, li4;
li1 = strtol (szNumbers,&pEnd,10);
li2 = strtol (pEnd,&pEnd,16);
li3 = strtol (pEnd,&pEnd,2);
li4 = strtol (pEnd,NULL,0);
printf ("The decimal equivalents are: %ld, %ld, %ld and %ld.\n", li1, li2, li3, li4);
return 0;
}
A more restricted version of your sscanf would be
int retaahn = sscanf(pointah,"%*[^0-9]%d%*[^0-9]",&numbeh);
Note that this doesn't change anything in your format string. I have just used 0-9 to mention the range and added a second %*[^0-9] to make things more explicit.
Currently using the above I'm getting garbage values, can someone
help?
Probably because you're not passing the right arguments to the function. Just do a
printf("pointah : %s\n",pointah);
to see what is passed or set breakpoints and debug your program.
So since my code was never wrong, it turns out my problem was how I was calling this function.
This is how I solved it:
I was calling it as:
parse_charstar("1000");
I tried:
parse_charstar(" 1000 "); // added spaces
And it worked!
Check my edit above for more!!
I've got some code which generates an array of strings of different file names and then
passes them into a function to write some data to them. It adds a incrementing number to the starting filename which is supplied from an input argument.
The problem is that it works fine running from source in Visual Studio 2012 but when I compile it and run it as an .exe the program crashes.
The .exe doesn't appear to be passing the array of strings properly which is causing an error when it attempts to use the string
for opening a file etc.
Here is the isolated bit of code
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>
#include <stdint.h>
#include <Windows.h>
void processing_function(int num_output, char **outnames)
{
/* in Visual Studio this works fine and prints all
the names correctly. Running from .exe will crash */
for(int idx = 0; idx <num_output;idx++)
{
printf("outnames[%d] is %s\n",idx,outnames[idx]);
}
}
int main(int argc, char *argv[])
{
/*nframes comes from another function, outname comes from input arguement */
int num_output = ceil(((double)*nframes / 1100));
int outname_len = strlen(outname)+1;
char *out_right;
out_right = (char*) malloc(sizeof(char)*outname_len);
/*Split string to append numbers before file extension */
strcpy(out_right,outname);
strrev(out_right);
strtok(out_right,".");
strcat(out_right,".");
strrev(out_right);
int out_right_len = strlen(out_right);
strtok(outname,".");
strcat(outname,"-");
int out_origlen = strlen(outname);
int num_len = 1;
char **outnames;
char *num;
char *outname_tmp;
outnames = (char**) malloc(sizeof(char)*(num_output));
int out_len;
double dbl_idx;
int *numfs = (int*)malloc(sizeof(int)*num_output);
for(int idx = 1;idx <num_output+1;idx++)
{
/*convert output number to string and stitch complete name back together and place into array */
num_len = ceil(log10((double)idx+0.1));
num = (char*) malloc(sizeof(char)*(num_len+1));
outname_tmp = (char*) malloc(sizeof(char)*(out_origlen+num_len+out_right_len+1));
strcpy(outname_tmp,outname);
sprintf(num,"%d",idx);
strcat(outname_tmp,num);
free(num);
strcat(outname_tmp,out_right);
outnames[idx-1] = (char*) malloc(sizeof(char)*(out_origlen+num_len+out_right_len+1));
strcpy(outnames[idx-1],outname_tmp);
free(outname_tmp);
printf("%s\n",outnames[idx-1]);
}
free(out_right);
processing_function(num_ouput, outnames)
return(0);
}
EDIT: Changed num_input to num_output as they do have the same value.
Running from .exe will sometimes start printing some of the names and then crash, opening the
debugger gives an error within output.c, with an access reading violation. I tried putting this code at
the top of the processing_function but that gave further problems downstream (heap corruption), which makes me think that the
code is messing up the memory but I can't see whats wrong with it, nor why it would work in VS but not as a .exe.
I could try and dodge the issue by generating the next output name on the fly every time it requires one but I'd really rather know why this isn't working.
Any help would be greatly appreciated.
I am going to take a shot and say, you passed num_input to processing_function() with outnames, outnames was allocated with num_output for size, but num_input and num_output have different values at runtime. So that lets processing_function() access out of bounds.
I encountered a problem while working on a project. I know there are many simillar questions that are answered, but regarding this special one I could not find any help. I am getting the following error:
Compiling main.c
main.c:42:1: error: expected identifier or '(' before '~' token
~
^
Makefile:47: recipe for target 'obj/main.o' failed
make: *** [obj/main.o] Error 1
EDIT: I deleted the last lines of the code, but the error still occures at the line after the last '}'.
The project is about the PageRank Algorithm, using options in the console for choosing what algorithm is wished to be used. I am trying to read or use the options in the command line, but the error stops me from even looking at the semantic of my program.
/*
* main.c
*
*Programmierung 2 - Projekt 2 (PageRank)
*/
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include "utils.h" //is existing in the Directory
int main (int argc, char *const *argv) {
//initialize the random number generator
rand_init();
printf("You gave %d command line arguments%c\n", argc-1, argc==1 ? '.' : ':');
int graph;
int i = 1;
char * h = "-h show this help. \n";
char * p = "...";
char * m = "...";
char * r = "...";
char * s = "...";
while ((graph = getopt(argc, argv, "hmprs")) != -1) {
switch (graph) {
default : printf("make -h | -m | -p | -r | -s "); break;
case 'h' : printf("%s %s %s %s %s"), h, m, p, r, s); break;
//this-like outcommended code like the one above
//and again
//and once more
//and a final one
}
printf(" - %s\n", argv[i]);
i++;
}
exit(0);
}
One more thing: I encountered a problem regarding the lengh of the case 'h' : printf(), so I outcoded the text in multiple chars.
If you need more information about anything, ask me.
The compiler reports an error on line 42, but the source in your question is only 33 lines and it contains no ~ character. You need to show us the entire source you're compiling.
But I have a good guess.
The error message shows a line with a ~ character in column 1 and nothing following it. The vi (or vim) text editor uses ~ to mark lines on the screen that aren't part of the file. If you copy-and-paste a source file from a vi editor session, it's easy to copy too many lines and end up with an extra ~ at the end of your source file.
Edit the file, jump to the end, and delete that line.
I got it now. My compiler (vim) added lines out of my sight. I used another editor and could delete the unnessecary code properly. Yes, was my bad all along. I am deeply sorry, it was a long day.