We have dump command in GDB which will dump a particular memory to a file. I want a command which will do exactly reverse of dump command i.e, which will read from a file of a particular length and dump it to specified address(memory).
Please help me on this regards, whether the command exists. If the command does not exists then please guide me how exactly i need to go ahead and implement it. As a am new to GDB.
I tried to use restore, but the problem is i need to load a file to a particular memory location some length. And in restore command syntax there is no such thing
A raw file [PATH] can be loaded to target's memory address [ADDR] with:
restore [PATH] binary [ADDR]
cf: GDB documentation
See the restore command:
restore -- Restore the contents of FILE to target memory
with python there is also the Inferior.write_memory function
Related
I have a C++ application which uses CCommandLineInfo to parse command line arguments.
One of these arguments is a password which we encrypt in memory with CryptProtectMemory after the application starts.
At that point I want to get rid of the password which is still in plain text available in memory (when I create a memory dump it can be retrieved).
Is there a way to clear the command line arguments? I tried clearing (overwriting with empty strings) __argv but the arguments were still visible in the memory dump.
[edit]
I tried clearing the commandline arguments like this, but that didn't work.
The arguments are still in memory.
for (int i=0; i<__argc; i++)
__argv[i] = "----------------------";
TCHAR* cmdLine = GetCommandLine();
SecureZeroMemory(cmdLine, strlen(cmdLine));
There is a well-known trick/hack to clear the command line from the process memory (see this answer), but even if you apply it you can still easily fetch the command line from e.g. Process Explorer since it makes a copy of it when the process is started. Thus, there is no way to prevent a tool like this from showing the command line.
Having a password as a command line parameter is simply a no-no. The only solution I can think of is to store the password encrypted/hashed (or worst case; unencrypted) in a file and then load that file as a parameter.
I'm afraid cleaning up argv is not enough, as the source of argv is still available using GetCommandLine(). Ultimately this information is stored in RTL_USER_PROCESS_PARAMETERS in Process Environment Block. C runtime will cache this information to argv. Some other library may cache this information too.
You'd better pass your sensitive data with other IPC - shared memory or pipe. Then you need to clean only your memory.
If you still want to locate original command line, here's approximate direction: NtCurrentTeb() to get TEB, then there would be pointer to PEB, and there would be pointer to RTL_USER_PROCESS_PARAMETERS, which finally contains pointer to command-line.
Inside a scripted gdb session I want to use monitor <cmd> where cmd should contain the address of a symbol. For example:
monitor foobar &myVariable
should become to:
monitor foobar 0x00004711
Because the remote side cannot evaluate the expression. Whatever I tried, the string "&myVariable" gets sent instead of the address.
I played around with convenience variables and stuff, but this is the only workaround I found:
# write the command into a file and execute this file
# didn't find a direct way to include the address into the monitor command
set logging overwrite on
set logging on command.tmp
printf "monitor foobar 0x%08x\n", &myVariable
set logging off
source command.tmp
Any ideas to solve this in a more elegant way?
The simplest way to do this is to use the gdb eval command, which was introduced for exactly this purpose. It works a bit like printf:
(gdb) eval "monitor foobar %p", &myVariable
(I didn't actually try this, so caution.)
If your gdb doesn't have eval, then it is on the old side. I would suggest upgrading.
If you can't upgrade, then you can also script this using Python.
If your gdb doesn't have Python, then it is either very old (upgrade!) or compiled without Python support (recompile!).
If you can't manage to get either of these features, then I am afraid the "write out a script and source it" approach is all that is left.
I have previously saved list of breakpoints using
save breakpoints blist
now after compiling the program when I try to reload the same break points with the load command
load blist
I get this error
You can't do that when your target is `exec'
How to resolve this ?
load blist
Try source blist instead.
From "help save breakpoints":
Save current breakpoint definitions as a script.
The way to read a script is the source command. The load command means something different entirely.
I have breakpoints saved to file, say gdb.br, file content looks like:
br /project/src/file.c : 100
commands
silent
printf "\nbacktrace:\n"
bt
cont
end
This break just output backtrace and continue execution. You may also use simple breaks, like:
br /project/src/file.c : 100
br className::methodName
I have a lot of breaks there - gdb fails to add them via copy-past. Also I can't use load command on my multi-threading system.
To attach with gdb and load breakpoints I use this sequence:
gdb -p 1523 -x gdb.br
Where 1523 is process pid you want to attach to. -x is primarily
intedent to be used to load commands, set environment, but also could be used to load your breaks.
Hope this will help.
I am using int res = system("uname -p"); in my c++ code.
It will give the the result in standard output by using
fprintf(stdout,"execution returned %d.\n",res);
I want to store this result string in a variable, I am unable to store it.
I google it but unable to find proper solution, Can any one tell me the correct way.
First, you don't need to run the uname command programmatically to get your processor. You can simply run the uname(2) syscall (which the uname command invokes). And you could also read and parse /proc/cpuinfo from your program.
If you wanted to read the output of some command, use popen(3) library function.
See also my answer to a related question.
I'm running a program that does processing on a file.
I want to be able to supply the program with several files, and by attaching to it with gdb, I want to get a memory dump at a certain point in the code for each of the files. I want the dump for each file to go to a file with the same filename as the input file (maybe after formatting it a little, say adding a suffix)
So suppose I have a function called HereIsTheFileName(char* filename), and another function called DumpThisMemoryRegion(void* startAddr, void* endAddr), I want to do something like the following:
To get the file name to an environment variable:
break HereIsTheFileName
commands 1
set $filename = malloc(strlen(filename) + 1)
call memcpy($filename, filename, strlen(filename) + 1)
end
Then to dump the memory to the filename I saved earlier:
break DumpThisMemoryRegion
commands 2
append binary memory "%s.memory"%$filename startAddr endAddr
end
(I would even settle for the filename as it is, without formatting, if that turns out to be the difficult part)
However, I couldn't get gdb to accept anything except an exlicit file name for the append/dump commands. when I ran "append binary memory $filename ..." I got the output in the file "/workdir/$filename".
Is there any way to make gdb choose the file name at runtime?
Thanks!
I don't know how to make append accept a runtime filename, but you can always cheat a bit by writing the whole thing to a file and then sourcing that file, using logging.
By putting this in your ~/.gdbinit
define reallyappend
printf "using gdbtmp.log to dump memory to file %s\n", $arg0
set logging file gdbtmp.log
set logging overwrite on
set logging redirect on
set logging on
printf "append binary memory %s 0x%x 0x%x", $arg0, $arg1, $arg2
set logging off
set logging redirect off
set logging overwrite off
source gdbtmp.log
end
you can use the function reallyappend instead, for example with
(gdb) set $filename = "somethingruntimegenerated"
(gdb) reallyappend $filename startAddr endAddr
I don't know if logging works ok in an "commands" environment, but you can give it a shot at least.
Yeah, you can't use a variable here for the filename argument.
The best suggestion I can offer is to write a script that will
set all the breakpoints and set up the "append" commands, and
use text editing or awk and sed to set up the filenames in the
script.