Ignore some locations in Windbg Conditional breakpoints - windbg

I'm trying to set a conditional hardware breakpoint on Windows Kernel-Mode in Windbg by using the following syntax :
ba w1 ffff802312345678 "j(#rip==ffff802387654321 || #rip==ffff802387654330) 'gc';''"
I used the above command in order to ignore every access to my target location (ffff802312345678) from ffff802387654321 or ffff802387654330, so everytime access from somewhere else is taken, then I would be notified.
But the problem is, it still breaks on ffff802387654321 or ffff802387654330 among the other locations.
I also read it's official documents about "Conditional Breakpoints and Register Sign Extension" and also test something like this:
ba w1 ffff802312345678 "j((#rip & 0xffffffffffffffff)=ffff802387654321 || (#rip & 0xffffffffffffffff)=ffff802387654330) 'gc';''"
But it still won't work.
So my question is:
What's wrong with the above command and how can I achieve the desired
result ?

There is no || MASM operator. It's or.
Use
ba w1 ffff802312345678 "j(#rip==ffff802387654321 or #rip==ffff802387654330) 'gc';''"
I have not reproduced your exact case, but a simpler example:
0:000> r rip
rip=0000000076db6fb0
0:000> j (#rip==0000000076db6fb0 || #rip==0) '.echo 5';'.echo 6"
Numeric expression missing from '| #rip==0) '.echo 5';'.echo 6"'
0:000> j (#rip==0000000076db6fb0 or #rip==0) '.echo 5';'.echo 6"
5

Related

windbg help missing kernel32 function

I am trying to follow this tutorial here https://www.microsoftpressstore.com/articles/article.aspx?p=2201303 specifically the part where it mentions x kernel32!writeprocessmemory
I am unable to find the method kernel32!WriteProcessMemory = even though documentation mentions it but i can find
kernel32!_imp__WriteProcessMemory and kernel32!WriteProcessMemoryStub. I am new to windbg and trying to follow the tutorial so i am not sure if this method has been deprecated and if so, what is it's substitute and how do we achieve similar functionality.
Thanks
The exported WriteProcessMemory function in fact points to the kernel32!WriteProcessMemoryStub stub which itself jumps onto the kernel32!__imp_WriteProcessMemory which redirects to the kernelbase DLL which is the "real" location for this function.
Let's check with a link dump:
C:>link /dump /exports c:\windows\system32\kernel32.dll | findstr /I WriteProcess
1579 62A 00036C50 WriteProcessMemory
0x36C50 is the RVA where the function "WriteProcessMemory" resides in kernel32 (as given by the export table). Now in windbg:
0:007> ln kernel32 + 0x36c50
Browse module
Set bu breakpoint
(00007ff9`4a6e6c50) KERNEL32!WriteProcessMemoryStub | (00007ff9`4a6e6c60) KERNEL32!ZombifyActCtxStub
We have an exact match which is in fact the KERNEL32!WriteProcessMemoryStub function. If we look at it:
0:007> u KERNEL32!WriteProcessMemoryStub
KERNEL32!WriteProcessMemoryStub:
00007ff9`4a6e6c50 48ff2599150400 jmp qword ptr [KERNEL32!_imp_WriteProcessMemory (00007ff9`4a7281f0)]
00007ff9`4a6e6c57 cc int 3
We can see it's just a jump to KERNEL32!_imp_WriteProcessMemory (located somewhere in the .idata section of kernel32).
Now if we look at what is contained at this location, we have a pointer:
0:007> dp KERNEL32!_imp_WriteProcessMemory L1
00007ff9`4a7281f0 00007ff9`496f0ca0
If we ask windbg what is this pointer:
0:007> ln 00007ff9`496f0ca0
Browse module
Set bu breakpoint
(00007ff9`496f0ca0) KERNELBASE!WriteProcessMemory | (00007ff9`496f0dc4) KERNELBASE!OpenWow64CrossProcessWorkConnection
Exact matches:
KERNELBASE!WriteProcessMemory (void)
We can see that in fact the "real" location for the WriteProcessMemory is in fact in kernelbase.dll.
note: you can actually do the last two commands in one with dps:
0:007> dps KERNEL32!_imp_WriteProcessMemory L1
00007ff9`4a7281f0 00007ff9`496f0ca0 KERNELBASE!WriteProcessMemory
Windbg command used:
ln (List Nearest Symbols): given an address, find the nearest symbol.
u (unassemble): used to disassemble a function
dp (display memory): display memory (pointer sized).
dps(Display Words and Symbols): as dp but with symbolic information.

Why can't we pass *,<,> via commandline arguments in C ? Whats happening in background?

I know the root cause is how C compiler handles string. But can anyone tell me what exactly these characters are accepted as ? And how can we pass them via commandline(I know adding '\' will make the system accept it, but how can I pass * or < or > as it is ?? I am using gcc compiler; is it a gcc specific issue ?
This has nothing to do with your C program. The problem is that *, < and > are special characters that the shell processes before they even reach your program. You could shield them from the shell by quoting your input with single quotes ('). E.g.:
$ ./myprogram arg1 arg2 'arg3<>*'

Querying from the terminal doesn't print anything

When ran in the command line, this
swipl -g "write(42)" -t "halt"
prints 42 to STDOUT as expected.
However, this
swipl -g "X = 42" -t "halt"
does not print anything, it simply returns.
How do I get it to print what it prints in the REPL (that is, X = 42)?
Note: this is in a Windows terminal. Let me know if this actually works in a Linux terminal.
As expected, X = 42 by itself produces no output whatsoever, because (=)/2 is a completely pure predicate that does not yield any side effects by itself. This is the case on Window, OSX and all other operating systems.
Even if there were a way to obtain and redirect the toplevel output itself, the fact remains that the SWI toplevel is subject to change and you cannot rely on future versions to behave in the same way as it does now. Long term, you will likely be better off to roll your own toplevel and produce exactly the output you want.
It is not so hard to roll your own toplevel. The trick is mainly to use the variable_names/1 option when reading terms, so that you can keep track of the variable names that you want to show in answers. Here is a very simplistic start:
repl :-
read_line_to_codes(current_input, Codes),
read_term_from_codes(Codes, Term, [variable_names(NameVars)]),
call(Term),
report_bindings(NameVars).
repl :- repl.
report_bindings(NameVars) :-
phrase(bindings(NameVars), Bs),
format("~s", [Bs]).
bindings([]) --> [].
bindings([E]) --> name_var(E).
bindings([E1,E2|Rest]) --> name_var(E1), ",\n", bindings([E2|Rest]).
name_var(Name=Var) -->
format_("~w = ~q", [Name,Var]).
format_(Format, Ls) -->
call(format_codes(Format, Ls)).
format_codes(Format, Ls, Cs0, Cs) :-
format(codes(Cs0,Cs), Format, Ls).
Example:
?- repl.
|: X = 4, between(1, 3, Y).
X = 4,
Y = 1
true ;
X = 4,
Y = 2
true ;
X = 4,
Y = 3
true ;
|: X = 7.
X = 7
It is easy to modify this so that it works on terms that are specified as arguments.
Note that the variable_names/1 option is essential for reading terms in such a way, and thanks to the ISO standardization effort an increasing number of implementations provide it for read_term/2 and related predicates.
This ability to read variable names is a requirement for implementing a portable Prolog toplevel!
The main exercise that I leave for you is to check if the quoting is right in all cases and (if desired) to produce answers in such a way that they can always be pasted back on the terminal. To extend this to residual constraints, use copy_term/3 and call_residue_vars/2 to collect pending constraints that you can append to the bindings.

Swift LLDB is not changing values / has no effect

having a code like this:
var foo: Int = 0
print (foo)
With a breakpoint at the print line... then doing:
(lldb) exp foo = 7
(lldb) p foo
(Int) $R2 = 7
0
print(x) still returns 0 instead of 7. How is that possible?
More details would help, but in general, I have seen this happen in three cases:
1) When you have a let, the compiler is free to replace the let with its value. This is not your case, but for sake of argument, given:
let x = 0
print(x)
The compiler is free to rewrite this as
print(0)
leaving the let binding in only for the sake of the debugger. Now, a let is a let, so writing to it is not exactly a well-defined operation. With that said, C compilers seem to not take that same kind of approach with const values, so that failure mode might surprise somebody
2) If you call a function, the compiler is (essentially) going to emit code to push the arguments on the stack, and then jump to the code for the function. In theory, one would expect the line table in the debug info to guide the debugger to stop before the arguments are pushed. Then,
>> push x
call print
A write to x would actually "mean" something in the context of your print call. But, if the line tables actually make us stop at the call, even if you write to "x", it has already been pushed, and the old value will be used
3) The compiler might actually be using a copy of "foo" that is in a register, but for the sake of debug info, pointing us to a stack copy of "foo" which is actually never used, and only updated when writes to "foo" happen. If that is the case, LLDB will gladly write to the stack, but that won't affect the program's behavior as it is not actually reading from the stack
Fun things to try to figure this out include:
the LLDB disassemble command
(lldb) reg read pc
(lldb) dis -s <value of program counter>
or
(lldb) fr var -L foo
and then read at the memory address (or the register) that LLDB gives out as the location of "foo"
or
in your app, print(x) twice, and see if the second print shows a different value

How to use command line arguments in Fortran?

GCC version 4.6
The Problem: To find a way to feed in parameters to the executable, say a.out, from the command line - more specifically feed in an array of double precision numbers.
Attempt: Using the READ(*,*) command, which is older in the standard:
Program test.f -
PROGRAM MAIN
REAL(8) :: A,B
READ(*,*) A,B
PRINT*, A+B, COMMAND_ARGUMENT_COUNT()
END PROGRAM MAIN
The execution -
$ gfortran test.f
$ ./a.out 3.D0 1.D0
This did not work. On a bit of soul-searching, found that
$./a.out
3.d0,1.d0
4.0000000000000000 0
does work, but the second line is an input prompt, and the objective of getting this done in one-line is not achieved. Also the COMMAND_ARGUMENT_COUNT() shows that the numbers fed into the input prompt don't really count as 'command line arguments', unlike PERL.
If you want to get the arguments fed to your program on the command line, use the (since Fortran 2003) standard intrinsic subroutine GET_COMMAND_ARGUMENT. Something like this might work
PROGRAM MAIN
REAL(8) :: A,B
integer :: num_args, ix
character(len=12), dimension(:), allocatable :: args
num_args = command_argument_count()
allocate(args(num_args)) ! I've omitted checking the return status of the allocation
do ix = 1, num_args
call get_command_argument(ix,args(ix))
! now parse the argument as you wish
end do
PRINT*, A+B, COMMAND_ARGUMENT_COUNT()
END PROGRAM MAIN
Note:
The second argument to the subroutine get_command_argument is a character variable which you'll have to parse to turn into a real (or whatever). Note also that I've allowed only 12 characters in each element of the args array, you may want to fiddle around with that.
As you've already figured out read isn't used for reading command line arguments in Fortran programs.
Since you want to read an array of real numbers, you might be better off using the approach you've already figured out, that is reading them from the terminal after the program has started, it's up to you.
The easiest way is to use a library. There is FLAP or f90getopt available. Both are open source and licensed under free licenses.
The latter is written by Mark Gates and me, just one module and can be learned in minutes but contains all what is needed to parse GNU- and POSIX-like command-line options. The first is more sophisticated and can be used even in closed-source projects. Check them out.
Furthermore libraries at https://fortranwiki.org/fortran/show/Command-line+arguments
What READ (*,*) does is that it reads from the standard input. For example, the characters entered using the keyboard.
As the question shows COMMAND_ARGUMENT_COUNT() can be used to get the number of the command line arguments.
The accepted answer by High Performance Mark show how to retrieve the individual command line arguments separated by blanks as individual character strings using GET_COMMAND_ARGUMENT(). One can also get the whole command line using GET_COMMAND(). One then has to somehow parse that character-based information into the data in your program.
I very simple cases you just need the program requires, for example, two numbers, so you read one number from arg 1 and another form arg 2. That is simple. Or you can read a triplet of numbers from a single argument if they are comma-separated like 1,2,3 using a simple read(arg,*) nums(1:3).
For general complicated command line parsing one uses libraries such as those mentioned in the answer by Hani. You have set them up so that the library knows the expected syntax of the command line arguments and the data it should fill with the values.
There is a middle ground, that is still relatively simple, but one already have multiple arguments, that correspond to Fortran variables in the program, that may or may not be present. In that case one can use the namelist for the syntax and for the parsing.
Here is an example, the man point is the namelist /cmd/ name, point, flag:
implicit none
real :: point(3)
logical :: flag
character(256) :: name
character(1024) :: command_line
call read_command_line
call parse_command_line
print *, point
print *, "'",trim(name),"'"
print *, flag
contains
subroutine read_command_line
integer :: exenamelength
integer :: io, io2
command_line = ""
call get_command(command = command_line,status = io)
if (io==0) then
call get_command_argument(0,length = exenamelength,status = io2)
if (io2==0) then
command_line = "&cmd "//adjustl(trim(command_line(exenamelength+1:)))//" /"
else
command_line = "&cmd "//adjustl(trim(command_line))//" /"
end if
else
write(*,*) io,"Error getting command line."
end if
end subroutine
subroutine parse_command_line
character(256) :: msg
namelist /cmd/ name, point, flag
integer :: io
if (len_trim(command_line)>0) then
msg = ''
read(command_line,nml = cmd,iostat = io,iomsg = msg)
if (io/=0) then
error stop "Error parsing the command line or cmd.conf " // msg
end if
end if
end subroutine
end
Usage in bash:
> ./command flag=T name=\"data.txt\" point=1.0,2.0,3.0
1.00000000 2.00000000 3.00000000
'data.txt'
T
or
> ./command flag=T name='"data.txt"' point=1.0,2.0,3.0
1.00000000 2.00000000 3.00000000
'data.txt'
T
Escaping the quotes for the string is unfortunately necessary, because bash eats the first quotes.