Address to WCHAR_T to pass to ReadProcessMemory - javascript

I'm having trouble passing a WCHAR_T to ReadProcessMemory
This is how to succesfully pass a pointers address to ReadProcessMemory, I can do it with structures:
remote_tbb = ralloc_alloc(struct_TBButton.size);
var rez = SendMessage(hToolbar, TB_GETBUTTON, i, ctypes.voidptr_t(remote_tbb));
if (!rez) { throw new Error('Failed on SendMessage of TB_GETBUTTON') }
var local_tbb = new struct_TBButton();
var retRead = ralloc_read(remote_tbb, local_tbb.address());
var freed = ralloc_free(remote_tbb);
But now I need to do with WCHAR_T, so this is what I have:
var chars = SendMessage(hToolbar, TB_GETBUTTONTEXTW, local_tbb.idCommand, ctypes.voidptr_t(0));
console.log('chars=', chars, chars.toString(), uneval(chars));
if (chars && parseInt(chars.toString()) > 0) {
var remote_buf = ralloc_alloc(parseInt(chars.toString()));
var charsRe = SendMessage(hToolbar, TB_GETBUTTONTEXTW, local_tbb.idCommand, ctypes.voidptr_t(remote_buf));
console.log('charsRe=', charsRe);
var local_buf = ctypes.jschar; //WCHAR_T
var retRead = ralloc_read(remote_buf, local_buf.address()); ///PROBLEM LINE
console.log('retRead=', retRead);
var freed = ralloc_free(remote_buf);
console.log('freed=', freed);
console.log('Button Text = ', local_buf, local_buf.toString());
} else {
console.log('Button Text = NONE');
}
So my problem is on line:
var retRead = ralloc_read(remote_buf, local_buf.address());`
and it is specifically on the local_buf.address()
Errors in my experimenting that get thrown are:
expected type pointer, got ctypes.jschar
local_buf.address is not a function
So how to pass WCHAR_T as reference?
Edit:
Here is my ralloc_read implemetnation:
function ralloc_read(remote_address, local_buffer) {
var found_addr;
for (var i = 0; i < buffers.length; i++) {
if (buffers[i][0] == remote_address) {
found_addr = buffers[i]
break;
}
}
if (!found_addr) {
return null;
}
/*using the found remote address(found_addr[0]),
*i read size bytes (found_addr[1]) into my local_buffer*/
//console.info('found_addr[0]', found_addr[0].toString());
var rez = ReadProcessMemory(proc, found_addr[0], local_buffer, found_addr[1], 0);
return rez;
}

If ralloc_read calls ReadProcessMemory, then you'll need to allocate a jschar array that will receive the result.
var local_buf = ctypes.jschar.array()(chars);
ralloc_read(remote_buf, local_buf.address());
var str = local_buf.readString();
Edit However, the allocation call is wrong:
ralloc_alloc(parseInt(chars.toString()));
This will allocate chars bytes, e.g. chars = 11, 11 bytes.
A wchar_t/jschar however is not 1 byte but 2 bytes.
ctypes.jschar.size
// 2
So you'll actually need to allocate a remote memory buffer that is larger:
ralloc_alloc(parseInt(chars.toString()) * ctypes.jschar.size);
// That would be ralloc_alloc(count * sizeof(wchar_t*)) in C/C++
The local_buf stuff is correct, though as js-ctypes arrays will automatically calculate the required storage if it knows the size of the array element type, so a ctypes.jschar.array()(11) buffer will actually have 11 elements of size 2 bytes, i.e. 11 items * 2 bytes/item == 22 bytes.

Related

Problem with creating multiple OBX segments in Mirth Connect

I have DB from where I'm getting my data of measurements. This is my code for looping through my measurements and adding them to OBX segments:
//getting MeasurementsData
var data = msg['measurements_measurement_data'].toString();
logger.info(data);
//inserting data in dictionary
var dictMeasurements = {};
for (var measurement in data) {
dictMeasurements[measurement] = data[measurement];
}
var dictSize = Object.keys(dictMeasurements).length;
var measureResult;
var measureType;
var counter = 1;
//Creating OBX measurements segments
while (counter <= dictSize) {
for (var key in dictMeasurements) {
//measure and result of measure
measureType = key;
measureResult = dictMeasurements[key];
createSegment('OBX', tmp, counter);
tmp['OBX'][counter]['OBX.1']['OBX.1.1'] = counter;
//ST-string or NM-numeric
tmp['OBX'][counter]['OBX.2']['OBX.2.1'] = isNumeric(measureResult);
tmp['OBX'][counter]['OBX.3']['OBX.3.1'] = ('ABI.' + measureType);
tmp['OBX'][counter]['OBX.3']['OBX.3.2'] = measureType;
tmp['OBX'][counter]['OBX.5']['OBX.5.1'] = measureResult;
tmp['OBX'][counter]['OBX.11']['OBX.11.1'] = 'F';
counter++;
}
}
If I run this code locally, it returns what I want (measurement type and its result), like:
cuffSizeArmLeft
1
cuffSizeArmRight
1
diaArmLeft
66
diaArmRight
66
But when I run it on MirthConnect chanel I get every letter from measure type in it's own column:
ST|ABI.0^0||{||||||F
OBX|2|ST|ABI.1^1||"||||||F
OBX|3|ST|ABI.2^2||c||||||F
OBX|4|ST|ABI.3^3||u||||||F
OBX|5|ST|ABI.4^4||f||||||F
OBX|6|ST|ABI.5^5||f||||||F
OBX|7|ST|ABI.6^6||S||||||F
OBX|8|ST|ABI.7^7||i||||||F
OBX|9|ST|ABI.8^8||z||||||F
OBX|10|ST|ABI.9^9||e||||||F
OBX|11|ST|ABI.10^10||A||||||F
OBX|12|ST|ABI.11^11||r||||||F
OBX|13|ST|ABI.12^12||m||||||F
OBX|14|ST|ABI.13^13||L||||||F
OBX|15|ST|ABI.14^14||e||||||F
OBX|16|ST|ABI.15^15||f||||||F
OBX|17|ST|ABI.16^16||t||||||F
OBX|18|ST|ABI.17^17||"||||||F
and my key in for loop is returning some numbers instead of measurement type, like it does locally.
This is similar question, but it didn't helped me.
Creating OBX segments from multiple DB rows
My another problem is that my function "isNumeric", is always returning a ST(string) instead a NM(numeric) type. Locally runs perfect.
function isNumeric(result) {
var reg = /^\d*\.?\d+$/;
if (typeof(result) == 'number') { return 'NM'; }
else { return 'ST'; }
}
console.log(isNumeric(140)); //return NM
console.log(isNumeric('test')); //return ST
Thanks for your help!

Copy array --> stack or heap overflow?

I have an array named globalArrayAllTrades as you see below. I simply like to INVERT the date in a new copy of the array. So I loop through, create a new object and add it to the new array - simple.
Then function does exactly as expected. BUT if the array contains too many objects the code fails with a "FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory".
My laptop has 8 GB of memory...When the NODEJS process crashes it uses about 1.5 GB and about 70% of of totally amount of available memory is used.
I do run the NODEJS app with the parameter: --max_old_space_size=5000 which normally fixes every thing. But not this one and i have tried MANY different ways to code the same function - BUT each and every time - it fails...unless the original array is smaller.
How can I fix this issue?
function invertTrades(){
var original = globalArrayAllTrades.slice();
globalArrayAllTrades.length = 0;
globalListAllTrades.length = 0;
for(var i = 0; i < original.length; i++){
var objS = original[i];
var objE = original[original.length-1-i];
var objInv = new TradePoint(objS.number, objS.matchdate, objE.price, objE.size, objE.issell);
globalArrayAllTrades.push(objInv);
globalListAllTrades[objInv.matchdate] = objInv;
}
}
You can save some memory by making original just contain the properties you need to invert, not the whole TradePoint object. Then you don't need to construct new TradePoint objects, you can modify them in place.
var original = globalArrayAllTrades.map(function(trade) {
return {
trade.price,
trade.size,
trade.issell
};
}).reverse();
globalArrayAllTrades.forEach(function(trade, i) {
trade.price = original[i].price;
trade.size = original[i].size;
trade.issell = original[i].issell;
});
And since all the objects were modified in place, there's no need to update globalListAllTrades.
Another way is to swap the price, size, and issell properties in place between the pairs of elements:
var midpoint = Math.floor(globalArrayAllTrade.length/2);
for (var i = 0; i < midpoint; i++) {
var objS = globalArrayAllTrades[i];
var objE = globalArrayAllTrades[globalArrayAllTrades.length-1-i];
var temp = objS.price;
objS.price = objE.price;
objE.price = temp;
temp = objS.size;
objS.size = objE.size;
objE.size = temp;
temp = objS.issell;
objS.issell = objE.issell;
objE.issell = temp;
}
Have you considered just doing this?
// Copy array and then reverse it
var newArray = [].concat(original).reverse();
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse
I would suggest avoiding to copy that array:
function getInverse(i) {
var objS = globalArrayAllTrades[i];
var objE = globalArrayAllTrades[globalArrayAllTrades.length-1-i];
var objInv = new TradePoint(objS.number, objS.matchdate, objE.price, objE.size, objE.issell);
globalListAllTrades[objInv.matchdate] = objInv;
return objInv;
}
function invertTrades(){
globalListAllTrades.length = 0;
for (var i = 0, l = Math.floor(globalArrayAllTrades.length/2); i < l; i++) {
var j = globalArrayAllTrades.length-1-i;
var a = getInverse(i);
var b = getInverse(j);
globalArrayAllTrades[i] = a;
globalArrayAllTrades[j] = b;
}
}

MongoDB ObjectId parsing in JavaScript

Read the link:
http://docs.mongodb.org/manual/reference/object-id/
The link says that the ObjectId will have Time, Machine, Process Id & Counter values.
Then, how to parse a ObjectId in JavaScript and get those details?
In node we can make use of buffers to grab integers from a hex string.
.findOne(cond, function(err, doc){
// create a 12 byte buffer by parsing the id
var ctr = 0;
var b = new Buffer(doc._id.str, 'hex');
// read first 4 bytes as an integer
var epoch = b.readUInt32BE(0);
ctr += 4;
// node doesn't have a utility for 'read 3 bytes' so hack it
var machine = new Buffer([0, b[ctr], b[ctr+1], b[ctr+2]]).readUInt32BE(0);
ctr += 3;
// read the 2 byte process
var process = b.readUInt16BE(ctr);
ctr += 2;
// another 3 byte one
var counter = new Buffer([0, b[ctr], b[ctr+1], b[ctr+2]]).readUInt32BE(0);
});
For driver version <2.2 change doc._id.str to doc._id.toHexString().
The potentially simpler technique is to just use parseInt and slice. Because hex digits are half of a byte our offsets are twice as high.
var id = doc._id.str, ctr = 0;
var epoch = parseInt(id.slice(ctr, (ctr+=8)), 16);
var machine = parseInt(id.slice(ctr, (ctr+=6)), 16);
var process = parseInt(id.slice(ctr, (ctr+=4)), 16);
var counter = parseInt(id.slice(ctr, (ctr+=6)), 16);

Binary Data Receive through Websocket

I have web socket application in C# and other I have small html page that connect to my Web socket and then send the message it receives correctly on my Web socket C# application.
The problem comes when i try to send the image data. First I get the image data into base 64 string and then convert the string into Uint8Array through JavaScript and send that array buffer to my C# Websocket application.
The data length is same but when I try to convert the byte array that I have received from web browser to my C# application it does not properly convert into Base 64 string and get a proper image on my C# application.
Please see the code
Java Script side :
function StringToBinary(string) {
var chars, code, i, isUCS2, len, _i;
len = string.length;
chars = [];
isUCS2 = false;
for (i = _i = 0; 0 <= len ? _i < len : _i > len; i = 0 <= len ? ++_i : --_i) {
code = String.prototype.charCodeAt.call(string, i);
if (code > 255) {
isUCS2 = true;
chars = null;
break;
} else {
chars.push(code);
}
}
if (isUCS2 === true) {
return unescape(encodeURIComponent(string));
} else {
return String.fromCharCode.apply(null, Array.prototype.slice.apply(chars));
}
}
function StringToUint8Array(string) {
var binary, binLen, buffer, chars, i, _i;
binary = StringToBinary(string);
binLen = binary.length;
buffer = new ArrayBuffer(binLen);
chars = new Uint8Array(buffer);
for (i = _i = 0; 0 <= binLen ? _i < binLen : _i > binLen; i = 0 <= binLen ? ++_i : --_i) {
chars[i] = String.prototype.charCodeAt.call(binary, i);
}
return chars;
}
function StringToArrayBuffer(string) {
return StringToUint8Array(string).buffer;
}
//Canvas to get the Base64string
var data = ctx.toDataURL('image/png')
var StringbinaryBuffer = StringToArrayBuffer(data);
webSocket.send(StringbinaryBuffer);
C# Code:
public static Frame FromBuffer(byte[] buffer)
{
var frame = new Frame();
// If no extended payload length and no mask are used, the payload starts at the 3rd byte
int payloadStartIndex = 2;
var firstNibble = (byte)(buffer[0] & 0xF0);
var secondNibble = (byte)(buffer[0] & 0x0F);
// When the first bit of the first byte is set,
// It means that the current frame is the final frame of a message
if (firstNibble == Fin)
frame.IsFin = true;
// The opcode consists of the last four bits in the first byte
//frame.Opcode = (Opcodes)secondNibble;
frame.Opcode = (Opcodes)secondNibble; ;
// The last bit of the second byte is the masking bit
bool isMasked = Convert.ToBoolean((buffer[1] & 0x80) >> 7);
// Payload length is stored in the first seven bits of the second byte
var payloadLength = (ulong)(buffer[1] & 0x7F);
// From RFC-6455 - Section 5.2
// "If 126, the following 2 bytes interpreted as a 16-bit unsigned integer are the payload length
// (expressed in network byte order)"
if (payloadLength == TwoBytesLengthCode)
{
Array.Reverse(buffer, payloadStartIndex, 2);
payloadLength = BitConverter.ToUInt16(buffer, payloadStartIndex);
payloadStartIndex += 2;
}
// From RFC-6455 - Section 5.2
// "If 127, the following 8 bytes interpreted as a 64-bit unsigned integer (the most significant bit MUST be 0)
// are the payload length (expressed in network byte order)"
else if (payloadLength == EightBytesLengthCode)
{
Array.Reverse(buffer, payloadStartIndex, 8);
payloadLength = BitConverter.ToUInt64(buffer, payloadStartIndex);
payloadStartIndex += 8;
}
frame.PayloadLength = payloadLength;
// From RFC-6455 - Section 5.2
// "All frames sent from the client to the server are masked by a
// 32-bit value that is contained within the frame. This field is
// present if the mask bit is set to 1 and is absent if the mask bit
// is set to 0."
if (isMasked)
{
frame.MaskingKey = BitConverter.ToInt32(buffer, payloadStartIndex);
payloadStartIndex += 4;
}
//buffer = new byte[(int)frame.PayloadLength + payloadStartIndex];
var content = new byte[frame.PayloadLength];
// Array.Copy(buffer, payloadStartIndex, content, 0, (int)frame.PayloadLength);
if (isMasked)
UnMask(content, frame.MaskingKey);
frame.UnmaskedPayload = content;
return frame;
}
private static void UnMask (byte[] payload, int maskingKey)
{
int currentMaskIndex = 0;
byte[] byteKeys = BitConverter.GetBytes(maskingKey);
for (int index = 0; index < payload.Length; ++index)
{
payload[index] = (byte)(payload[index] ^ byteKeys[currentMaskIndex]);
currentMaskIndex = (++currentMaskIndex)%4;
}
}
frame.UnmaskedPayload: this contains the full bytes of the message and I try to convert those bytes back to image.
But it gives the exception that its not valid parameter data.

Javascript: Uint16Array(length) returns Invalid argument

I'm trying to read a file in order to perform certain actions on the binary data before sending it to a server.
At a certain point I'm trying to convert the data returned by FileReader.readAsArrayBuffer() to an Uint16Array(). However upon doing so the code allocating the array fails with: 'Error: invalid arguments'. I need the data to be a hex string representing the entire binary.
This is the code I'm using:
function HexToHexString(ByteBuffer)
{
//Similar constructs like: 'var Array = new Uint16Array(ByteBuffer);' also fail
var View = new DataView(ByteBuffer);
var Array = new Uint16Array((ByteBuffer.byteLength / 2)); // <- this line fails
for(var i = 0; i < Array.length; i++)
{
Array[i] = View.getUint16(i*2);
}
return String.fromCharCode.apply(null, Array);
}
function OnReadFileCompletion(FileReadEvent)
{
if(FileReadEvent.target.readyState == FileReader.DONE)
{
// Debug code, will be replaced:
document.getElementById('byte_content').textContent = HexToHexString(FileReadEvent.target.result);
//FileReadEvent.target.result;
}
}
function ReadFile(File, ResultFunction)
{
var Reader = new FileReader();
Reader.onloadend = ResultFunction;
Reader.readAsArrayBuffer(File.slice(0, File.size - 1));
}
File Is a file object, ResultFunction is OnReadFileCompletion(), ByteBuffer is an '[object ArrayBuffer]'.
When I output the size of the ArrayBuffer it matches the size of the file (82kb). I'm on firefox 32 with no plugins installed.
I'm not a javascript programmer, does anyone know what I'm doing wrong?
Edit1:
It appears to have something to-do with the size of the file I'm trying to read, using a 1kb text file appears to work while a 82kb binary file does not.
Edit2
I spoke too soon, perhaps it has something to do with file types. An image file of 200kb works, while an executable of 82 does not.
It appears that javascript does not allow executable files to be accesed this way, does anybody know of any way where I could possibly access the data in hex form?
try using .length instead of byteLength
I've hacked together code that works for me, I don't know why this works or what I did wrong the other time. But it works.
function ApplyPadding(Number, PaddingLength)
{
var s = Number + "";
while (s.length < PaddingLength)
s = "0" + s;
return s;
}
function HexToHexString(ByteBuffers)
{
var AnArray = new Uint8Array(ByteBuffers);
var Result = "";
for(var i = 0; i < AnArray.length; i++)
{
if(i%2==0)
Result += ApplyPadding(AnArray[i].toString(16), 2);
}
return Result;
}
function HexStringToHex(aString)
{
var Buffer = new ArrayBuffer(aString.length*2); // 2 bytes for each char
var BufferView = new Uint16Array(Buffer);
for (var i = 0;i < aString.length; i++)
{
BufferView[i] = aString.charCodeAt(i);
}
return Buffer;
}
function OnReadFileCompletion(FileReadEvent)
{
if(FileReadEvent.target.readyState == FileReader.DONE)
{
//document.getElementById('byte_content').textContent =FileReadEvent.target.result;
var DataOfFile = HexStringToHex(FileReadEvent.target.result);
var FinalData = HexToHexString(DataOfFile);
document.getElementById('byte_content').textContent = FinalData;
//FileReadEvent.target.result;
}
}
function ReadFile(File, ResultFunction)
{
var Reader = new FileReader();
Reader.onloadend = ResultFunction;
Reader.readAsBinaryString(File.slice(0, File.size - 1));
}

Categories