How do I read the contents of stack variables in IDA? - reverse-engineering

I notice that a char buffer has been allocated on the stack in a function. It goes like this:
.text:00401xxx Buffer= byte ptr -24h
I know that I can read Dwords at memory addresses by going:
Dword(0x<address>)
But, how do I do the same for stack variables? Specifically here, I'd like to be able to read the whole character buffer...

Yuo could use the idc IDA module, there are many interesting functions.
If you want print dword, this is correct: Dword(0x<address>)
For memory dumping as suggest above you could use follow function:
**GetManyBytes(ea, size, use_dbg=False)<br>**
Parameters:
ea - linear address
size - size of buffer in normal 8-bit bytes
use_dbg - if True, use debugger memory, otherwise just the database
An example:
GetManyBytes(0x<address>, 50, True)
You can call the function runtime, you could use also a simple script like:
from idc import GetManyBytes
from struct import unpack
def simple_dump():
arr = []
for i in xrange(0, 2*SIZE_TO_DUMP, 2):
bytes = GetManyBytes(0x<address>+i,2)
arr.append(unpack("h", bytes)[0])
return arr
def main():
values = simple_dump()
You can also use the IDA Hex-View windows

Related

Why can't I perform gradients on a variable passed as an argument to a tf.function?

My training loop was giving me the following warning:
WARNING:tensorflow:Gradients do not exist for variables ['noise:0'] when minimizing the loss.
After some tinkering I determined this only happened when the noise variable was being passed as an argument to my loss function which is a tf.function. The code below shows that there is no problem when the loss function is not a tf.function or when the global noise variable is referenced in the function. It also shows that an error results from trying to perform a gradient on the noise variable when it is used as argument in a tf.function:
import numpy as np
import tensorflow as tf
import tensorflow_probability as tfp
from tensorflow_probability import distributions as tfd
from tensorflow_probability import bijectors as tfb
constrain_positive = tfb.Shift(np.finfo(np.float64).tiny)(tfb.Exp())
noise = tfp.util.TransformedVariable(initial_value=.1, bijector=constrain_positive, dtype=np.float64, name="noise")
trainable_variables = [noise.variables[0]]
kernel = tfp.math.psd_kernels.ExponentiatedQuadratic()
optimizer = tf.keras.optimizers.Adam()
index_points = tf.constant([[0]], dtype=np.float64)
observations = tf.constant([0], dtype=np.float64)
# I can train noise when it is passed as an argument to a python function
def loss_function_1(index_points, observations, kernel, observation_noise_variance):
gp = tfd.GaussianProcess(kernel, index_points, observation_noise_variance=observation_noise_variance)
return -gp.log_prob(observations)
with tf.GradientTape() as tape:
nll_1 = loss_function_1(index_points, observations, kernel, noise)
grad_1 = tape.gradient(nll_1, trainable_variables)
print(grad_1)
optimizer.apply_gradients(zip(grad_1, trainable_variables))
# I can train noise if it is used in a tf.function and not passed as an argument
#tf.function(autograph=False, experimental_compile=False)
def loss_function_2(index_points, observations, kernel):
gp = tfd.GaussianProcess(kernel, index_points, observation_noise_variance=noise)
return -gp.log_prob(observations)
with tf.GradientTape() as tape:
nll_2 = loss_function_2(index_points, observations, kernel)
grad_2 = tape.gradient(nll_2, trainable_variables)
print(grad_2)
optimizer.apply_gradients(zip(grad_2, trainable_variables))
# I can train noise if it is passed as an argument to a tf.function if the tf.function
# uses the global variable
#tf.function(autograph=False, experimental_compile=False)
def loss_function_3(index_points, observations, kernel, observation_noise_variance):
gp = tfd.GaussianProcess(kernel, index_points, observation_noise_variance=noise)
return -gp.log_prob(observations)
with tf.GradientTape() as tape:
nll_3 = loss_function_3(index_points, observations, kernel, noise)
grad_3 = tape.gradient(nll_3, trainable_variables)
print(grad_3)
optimizer.apply_gradients(zip(grad_3, trainable_variables))
# I cannot train noise if it is passed as an argument to a tf.function if the tf.function
# the local variable
#tf.function(autograph=False, experimental_compile=False)
def loss_function_4(index_points, observations, kernel, observation_noise_variance):
gp = tfd.GaussianProcess(kernel, index_points, observation_noise_variance=observation_noise_variance)
return -gp.log_prob(observations)
with tf.GradientTape() as tape:
nll_4 = loss_function_4(index_points, observations, kernel, noise)
grad_4 = tape.gradient(nll_4, trainable_variables)
print(grad_4)
optimizer.apply_gradients(zip(grad_4, trainable_variables))
This code prints:
[<tf.Tensor: shape=(), dtype=float64, numpy=0.045454545454545456>]
[<tf.Tensor: shape=(), dtype=float64, numpy=0.045413242911911206>]
[<tf.Tensor: shape=(), dtype=float64, numpy=0.04537197429557289>]
[None]
And then it returns the error message:
ValueError: No gradients provided for any variable: ['noise:0'].
Ideally I would get the performance boost of a tf.function so I don't want to use loss_function_1. Also, I would like to be able to pass different noise variables to my loss function so I do not want to use the global variable like I do in loss_function_2 or loss_function_3.
Why do I get None when I try to perform a gradient on a variable passed as an argument to a tf.function? How can I get around this?
You can't workaround it, it works like that by design.
When you use tf.function you're converting the Python code to a static graph (in particular a DAG). This graph has some input nodes and some output nodes.
The input nodes are the parameter of your function and the output nodes are the return values.
Defining a tf.Variable inside the function body, or equivalently, passing a tf.Variable as a function parameter, means creating a new variable node in the static graph every time you invoke it and creating a new variable every time you call it it's now what you want.
In practice, when you have objects with a state (tf.Variable and similar) you can't define them inside a tf.function-decorated function, but you have to break the function scope and declare the variable outside it.
Your solution of declaring a global variable is the one to use. A better solution is to refactor your code to be more object-oriented, declaring the variable as a private attribute of a class in order to do not expose the variable object globally.
I covered this behavior in this article where you can find several insights on how to refactor your code and how to think when using tf.function

How to use Critcl ByteArray?

I want to try out Critcl to enhance memory performance using a Z-order curve for a 2d-grid. What I need from Critcl is allocation, setter, getter and some size info. Reading about the Critcl ByteArray and examples does not make me confident on how to do it.
How do I create and return a ByteArray (i.e. Z-order curve)?
Any caveats I should know about when using ByteArray?
According to the documentation, you should be using the bytes type instead (when you get a pointer to a structure that has a len field with the number of bytes in it, and an s field that is the pointer to the actual read only block of bytes. (As a char * and not an unsigned char * for reasons I don't know. And why it isn't const is another mystery to me; there are cases where that's indeed true, but you need to look at the o field to figure that out.)
To return a byte array, you use the object (or object0) result type, and make the object with, for example, Tcl_NewByteArrayObj(), or Tcl_NewObj() and Tcl_SetByteArrayLength().
Here's an example (just the command definition) that does trivial byte reversing (since I don't understand Z-order curves at all):
critcl::cproc example {bytes dataPtr} object0 {
Tcl_Obj *result = Tcl_NewObj();
unsigned char *targetBytes = Tcl_SetByteArrayLength(result, dataPtr->len);
for (int i = 0, j = dataPtr->len - 1; j >= 0; i++, j--) {
targetBytes[i] = (unsigned byte) dataPtr->s[j];
}
return result;
}
Naturally, you'll want to read the Critcl usage guide when getting this to work, and if you're going to produce errors (by returning NULL), remember to set an error message in the interpreter. You can get access to that by using Tcl_Interp* interp as your first pseudo-argument to the command you create with critcl::cproc (it's documented, but easily missed).

How to Paramatrized vector of registers in chisel

I need an example on how to paramtrize Vector of registers in terms of bit-width and initial values which are not '0' and are different for each register.
My use-case is a generic filter coefficients bank with some unique reset values to each, and off course an option to override values.
I thought of something like the below code (not really sure how to write the iteration, so this is kind of pseudo):
class Coeffbank(bitWidth : UInt ,ncoeff : UInt, rstVal : Vec(SInt)) extends Module {
// how do iterate through the reset vector ?? //
val coeffs = Vec.fill(ncoeff) {Reg(init = SInt(rstVal(i),width = bitwidth))
}
Also, when new'ing the above (instantiating this module how do I pass the list of reset value in the argument list?
Hoping to get some help on how to write it properly.
The explanation should probably be a bit more thorough, but basically you need to create a Reg of Vec. Something like should do it:
val coeffs = RegInit(rstVal)
In this case, since you already have the Vec of reset values, you can just pass it to the Reg constructor.
I'm assuming that the size of rstVal is equal to ncoeff, otherwise you'll need to reduce the size of rstVal with something like rstVal.take(ncoeff). Also note that I'm using RegInit which is the preferred way to create a register with a reset value.
Let's start with the easy case. This would be much easier if instead of a Vec of SInts your rstVal array was instead a scala collection (Seq, Array, ...) of regular SInt. When possible it is best to save generation of actual hardware until you directly need them. If rstVal contains Int's. Your code would become
val newRstVals = VecInit(Seq.tabulate(ncoeff) { index => rstVals(index).S(bitWidth.W) })
val reg = RegInit(newRstVals)
If you really need to pass in a Vec then the right approach is to create a separate type instance and use the two argument call to RegInit
val vecType = Vec(ncoeff, SInt(bitWidth.W))
val newRstVals1 = VecInit(Seq.tabulate(ncoeff) { index => newRstVals(index) })
val reg = RegInit(vecType, newRstVals1)
There might be problems if the bitWidth you pass in is not big enough to contain the constants you have passed in. You probably should have some checks for that.

How to Initialize a Register of Vectors?

I have defined a register of vectors like this
val my_reg = Reg(Vec(n, Bits(32.W)))
and I access the elements of this register in a for loop using my_reg(i).
Now, I like to initialize this register to zero, so I change the variable definition to this
val my_reg = Reg(Vec(n, Bits(32.W)), init = UInt(0))
However, I get the following compilation error when I want to access the elements of this register
chisel3.core.Data does not take parameters
my_reg(i) := io.a(i)
How can I define a register of vectors and properly initialize them synchronously?
Use RegInit instead. I believe the following statement will do what you want
val my_reg = RegInit(Vec(Seq.fill(n)(0.U(32.W))))
The Vector is initialized by a Seq of UInt zeros that are 32 bits wide
Looks like in Chisel 3 this should be VecInit instead of Vec:
val initRegOfVec = RegInit(VecInit(Seq.fill(4)(0.U(32.W))))
Source: https://github.com/freechipsproject/chisel3/wiki/Cookbook#how-do-i-create-a-reg-of-type-vec

D: How to create a new, empty binary heap to store integers?

I'm a bit confused about how to properly use the Binary Heap provided in std.container. More specifically, I wanted to create a maximum heap of integers, so I tried writing
auto maxHeap = BinaryHeap!int();
and got a compiler complaint about int not being sliceable with []. I've tried to read the documentation for it on Phobos, but I don't understand how to create a new, empty binary heap designed to store integers.
Could someone please lend me a hand?
There is an interesting thread about BinaryHeaps.
As it's explained in the thread, you can try to use it this way:
import std.container: Array, heapify;
void main()
{
int[] arr = [1, 2, 3];
auto wrapped = Array!int(arr);
auto queue = heapify(wrapped);
}
Well, I humbly believe you would not be confused if you read documentation about BinaryHeap.
The first sentence clearly explains the crucial information:
Implements a binary heap container on top of a given random-access range type (usually T[]) or a random-access container type (usually Array!T).
Here is what you should do:
import std.stdio;
import std.container;
void main(string[] args) {
int[] arr = [1, 4, 12, 19];
auto bh = BinaryHeap!(int[])(arr);
writeln(bh.length); // prints 4
}
It is worth of reminding people that D array is a random-access range.