How to get COR_PRF_FUNCTION_ARGUMENT_INFO from COR_PRF_ELT_INFO using GetFunctionEnter3Info function in ICorProfilerInfo3 interface - clr-profiling-api

I'm using CLR profiling API and trying to get arguments info (COR_PRF_FUNCTION_ARGUMENT_INFO) from COR_PRF_ELT_INFO using GetFunctionEnter3Info function.
Below is my code. It seems GetFunctionEnter3Info function is not setting the value for pArgumentInfo. It always has null value. However, the function returns S_OK, which is a success.
I may be missing something. How should I get COR_PRF_FUNCTION_ARGUMENT_INFO from COR_PRF_ELT_INFO ?
PROFILER_STUB EnterStub(FunctionIDOrClientID functionId, COR_PRF_ELT_INFO eltInfo)
{
COR_PRF_FRAME_INFO *pFrameInfo = 0;
ULONG *pcbArgumentInfo = 0;
COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo = NULL;
corProfilerInfo->GetFunctionEnter3Info(functionId.functionID, eltInfo, pFrameInfo, pcbArgumentInfo, pArgumentInfo);
if(pArgumentInfo) {
//
}
}

It is a little bit tricky,
By msdn doc:
pcbArgumentInfo
[in, out] A pointer to the total size, in bytes, of the COR_PRF_FUNCTION_ARGUMENT_INFO structure (plus any additional COR_PRF_FUNCTION_ARGUMENT_RANGE structures for the argument ranges pointed to by pArgumentInfo). If the specified size is not enough, ERROR_INSUFFICIENT_BUFFER is returned and the expected size is stored in pcbArgumentInfo. To call GetFunctionEnter3Info just to retrieve the expected value for *pcbArgumentInfo, set *pcbArgumentInfo=0 and pArgumentInfo=NULL
In other words, you have a single COR_PRF_FUNCTION_ARGUMENT_INFO structure, which references multiple COR_PRF_FUNCTION_ARGUMENT_RANGE.
First of all, get a number of bytes of pcbArgumentInfo, after that allocate bytes and pass the pointer to GetFunctionEnter3Info as COR_PRF_FUNCTION_ARGUMENT_INFO.
Here is an example
PROFILER_STUB EnterStub(FunctionIDOrClientID functionId, COR_PRF_ELT_INFO eltInfo)
{
ULONG pcbArgumentInfo = 0;
COR_PRF_FRAME_INFO frameInfo;
corProfilerInfo3->GetFunctionEnter3Info(functionIDOrClientID.functionID, eltInfo, &frameInfo, &pcbArgumentInfo, NULL);
char* pArgumentInfo = new char[pcbArgumentInfo];
corProfilerInfo3->GetFunctionEnter3Info(functionIDOrClientID.functionID, eltInfo, &frameInfo, &pcbArgumentInfo, (COR_PRF_FUNCTION_ARGUMENT_INFO*)pArgumentInfo);
COR_PRF_FUNCTION_ARGUMENT_INFO* ptr = (COR_PRF_FUNCTION_ARGUMENT_INFO*)pArgumentInfo;
}
To access the second argument info block of COR_PRF_FUNCTION_ARGUMENT_RANGE use
prt->ranges[1]
The number of blocks is written in ptr->numRanges

Related

I have an error trying to access iphdr using eBPF

So I've been trying to access the iphdr using eBPF.
static inline int parse_ipv4(void *data, u64 nh_off, void *data_end) {
struct iphdr *iph = data + nh_off;
if ((void*)&iph[1] > data_end)
return 0;
return iph->protocol;
}
When I use the code above in the eBPF function, it works fine like :
if (h_proto == htons(ETH_P_IP)){
index = parse_ipv4(data, nh_off, data_end);
Like this, calling parse_ipv4 function works.
However, if I try to access the ipheader directly without using the function, it doesn't work.
if (h_proto == htons(ETH_P_IP)){
index = parse_ipv4(data, nh_off, data_end);
struct iphdr *iph2 = sizeof(*eth) + nh_off;
}
This gives me an error : HINT: The invalid mem access 'inv' error can happen if you try to dereference memory without first using bpf_probe_read() to copy it to the BPF stack. Sometimes the bpf_probe_read is automatic by the bcc rewriter, other times you'll need to be explicit.
and fails to activate.
Thank you so much in advance!
Unless I misunderstand your program, the following:
struct iphdr *iph2 = sizeof(*eth) + nh_off;
looks erroneous. Instead, iph2 should be something like data + nh_off, just as in your function, no? If you set it to the sum of two sizes, without any base address, then you try to access data at an arbitrary memory location (something like 0x28 I guess), which of course is not permitted.

How to - SHA1 hash of plaintext using SHA1CryptoServiceProvider in C++/CLI?

I want to hash a string but looking at the example on MSDN I got stuck on the DATA_SIZE. What is this? and how do I know ahead of time what the size of the array is if the plaintext can vary in length?
Also I need to return the result as a vector (consuming method expects this)
Code from MSDN
array<Byte>^ data = gcnew array<Byte>( DATA_SIZE );
array<Byte>^ result;
SHA1^ sha = gcnew SHA1CryptoServiceProvider;
// This is one implementation of the abstract class SHA1.
result = sha->ComputeHash( data );
My method so far looks like
std::vector<byte> sha1(const std::string& plaintext)
{
//#define SHA1_BUFFER_SIZE ????
//array<System::Byte>^ data = gcnew array<System::Byte>(DATA_SIZE);
//convert plaintext string to byte array
array<System::Byte>^ result;
SHA1^ sha = gcnew SHA1CryptoServiceProvider;
result = sha->ComputeHash(data);
//return result as a vector<byte>
}
First, answering your questions:
On the referred MSDN page, it was stated before the example:
This example assumes that there is a predefined constant DATA_SIZE.
So, it was assumed that there was a #define or a enum constant predefined
Of course you don't know the size of the plaintext. But you'll see that in this approach you don't need the DATA_SIZE constant
If you want your function to receive as input a std:string and to output a std::vector, there are a lot of steps to be done. It would look something like that:
std::vector<unsigned char> sha1(const std::string& message)
{
// Steps #1 and #2: convert from std::string to managed string
// and convert from a string to bytes (UTF-8 as example)
array<Byte>^data = Encoding::UTF8->GetBytes(gcnew String(message.c_str() ));
// Steps #3 and #4: perform hash operation
// and store result in a byte array
SHA1^ sha = gcnew SHA1CryptoServiceProvider;
array<Byte>^ array_result = sha->ComputeHash(data);
// Step #5: convert from a managed array
// to unmanaged vector
std::vector<unsigned char> vector_return(array_result->Length);
Marshal::Copy(array_result, 0, IntPtr(&vector_return[0]), array_result->Length);
return vector_return;
}
don't forget to declare the namespaces you're using:
using namespace System;
using namespace System::Text;
using namespace System::Security::Cryptography;
using namespace System::Runtime::InteropServices;
int main(array<System::String ^> ^args)
{
std::string str_test("This is just a test.");
std::vector<unsigned char> vec_digest( sha1(str_test) );
return 0;
}
Final thoughts:
It's a bit misleading to name the string you want to hash as plaintext. More accurate terms would be message (for the input data) and digest (for the hash value)
Avoid mixing the use of std::string and managed String^ if you can.

How to get current position of iterator in ByteString?

I have an instance of ByteString. To read data from it I should use it's iterator() method.
I read some data and then I decide than I need to create a view (separate iterator of some chunk of data).
I can't use slice() of original iterator, because that would make it unusable, because docs says that:
After calling this method, one should discard the iterator it was called on, and use only the iterator that was returned. Using the old
iterator is undefined, subject to change, and may result in changes to
the new iterator as well.
So, it seems that I need to call slice() on ByteString. But slice() has from and until parameters and I don't know from. I need something like this:
ByteString originalByteString = ...; // <-- This is my input data
ByteIterator originalIterator = originalByteString .iterator();
...
read some data from originalIterator
...
int length = 100; // < -- Size of the view
int from = originalIterator.currentPosition(); // <-- I need this
int until = from + length;
ByteString viewOfOriginalByteString = originalByteString.slice(from, until);
ByteIterator iteratorForView = viewOfOriginalByteString.iterator(); // <-- This is my goal
Update:
Tried to do this with duplicate():
ByteIterator iteratorForView = originalIterator.duplicate()._2.take(length);
ByteIterator's from field is private, and none of the methods seems to simply return it. All I can suggest is to use originalIterator.duplicate to get a safe copy, or else to "cheat" by using reflection to read the from field, assuming reflection is available in your deployment environment.

Battery info from the Blackberry 10 SDK

I tried this code:
battery_info_t **pointer=NULL;
battery_get_info(pointer);
return battery_info_get_time_to_empty(*pointer); // needs simple pointer (*pointer)
My question is: how can i convert **pointer to *pointer
In this usage the battery_info_... function calls take a pointer to a battery_info_t type, so you would declare pointer as that and use it as the argument to those calls. To set pointer to the correct value you pass a pointer to it to battery_get_info(). You must also free the memory allocated to pointer when you are done:
battery_info_t *pointer = NULL;
battery_get_info(&pointer);
int t = battery_info_get_time_to_empty(pointer);
battery_free_info(&pointer);
return t;
This works:
battery_info_t *pointer=NULL;
battery_get_info(&pointer);
return battery_info_get_time_to_empty(pointer);
But returns 65535, on an emulator, so i can't tell if it works or not, because i don have an BB10...

Getting line locations with iText

How can one find where are lines located in a document with iText?
Suppose say I have a table in a PDF document, and want to read its contents; I would like to find where exactly the cells are located. In order to do that I thought I might find the intersections of lines.
I think your only option using iText will be to parse the PDF tokens manually. Before doing that I would have a copy of the PDF spec handy.
(I'm a .Net guy so I use iTextSharp but other than some capitalization differences and property declarations they're almost 100% the same.)
You can get the individual tokens using the PRTokeniser object which you feed bytes into from calling getPageContent(pageNum) on your PdfReader.
//Get bytes for page 1
byte[] pageBytes = reader.getPageContent(1);
//Get the tokens for page 1
PRTokeniser tokeniser = new PRTokeniser(pageBytes);
Then just loop through the PRTokeniser:
PRTokeniser.TokType tokenType;
string tokenValue;
while (tokeniser.nextToken()) {
tokenType = tokeniser.tokenType;
tokenValue = tokeniser.stringValue;
//...check tokenValue, do something with it
}
As far a tokenValue, you'd want to probably look for re and l values for rectangle and line. If you see an re then you want to look at the previous 4 values and if you see an l then previous 2 values. This also means that you need to store each tokenValue in an array so you can look back later.
Depending on what you used to create the PDF with you might get some interesting results. For instance, I created a 4 cell table with Microsoft Word and saved as a PDF. For some reason there are two sets of 10 rectangles with many duplicates, but the general idea still works.
Below is C# code targeting iTextSharp 5.1.1.0. You should be able to convert it to Java and iText very easily, I noted the one line that has .Net-specific code that needs to be adjusted from a Generic List (List<string>) to a Java equivalent, probably an ArrayList. You'll also need to adjust some casing, .Net uses Object.Method() whereas Java uses Object.method(). Lastly, .Net accesses properties without gets and sets, so Object.Property is both the getter and setter compared to Java's Object.getProperty and Object.setProperty.
Hopefully this gets you started at least!
//Source file to read from
string sourceFile = "c:\\Hello.pdf";
//Bind a reader to our PDF
PdfReader reader = new PdfReader(sourceFile);
//Create our buffer for previous token values. For Java users, List<string> is a generic list, probably most similar to an ArrayList
List<string> buf = new List<string>();
//Get the raw bytes for the page
byte[] pageBytes = reader.GetPageContent(1);
//Get the raw tokens from the bytes
PRTokeniser tokeniser = new PRTokeniser(pageBytes);
//Create some variables to set later
PRTokeniser.TokType tokenType;
string tokenValue;
//Loop through each token
while (tokeniser.NextToken()) {
//Get the types and value
tokenType = tokeniser.TokenType;
tokenValue = tokeniser.StringValue;
//If the type is a numeric type
if (tokenType == PRTokeniser.TokType.NUMBER) {
//Store it in our buffer for later user
buf.Add(tokenValue);
//Otherwise we only care about raw commands which are categorized as "OTHER"
} else if (tokenType == PRTokeniser.TokType.OTHER) {
//Look for a rectangle token
if (tokenValue == "re") {
//Sanity check, make sure we have enough items in the buffer
if (buf.Count < 4) throw new Exception("Not enough elements in buffer for a rectangle");
//Read and convert the values
float x = float.Parse(buf[buf.Count - 4]);
float y = float.Parse(buf[buf.Count - 3]);
float w = float.Parse(buf[buf.Count - 2]);
float h = float.Parse(buf[buf.Count - 1]);
//..do something with them here
}
}
}