Binary Data Receive through Websocket - javascript

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.

Related

Looping through an array that has binary numbers and writing true if the number is 1 or false if the number is 0

I am trying to make a webpage that makes an encrypted letter by first parsing a single character in ascii then parsing the ascii into binary then putting the binary into an array. After putting it into an array I have to loop through the array and write true for "1" or false for "0". Then I have to output to the page. an example of what the output would look like if you put in the letter "a" would be "false,true,true,false,false,false,false,true"
Update: I have added the "loop" in order to make sense of my problem
$(document).ready(function()
{
var output = document.getElementById("output");
var strQuestion = "Enter ONE character, matey!";
var strStandard = "J";
var chrCharacter = "";
var chrLength = 0;
var array = [];
var arrayLength = 0;
while (chrLength != 1)
{
chrCharacter = prompt(strQuestion, strStandard);
chrLength = chrCharacter.length;
}
intAscii = parseAscii(chrCharacter);
strBin = parseBin(intAscii);
array = strBin.split("");
for (i = 0; i < arrayLength; i++ )
{
if (array[i] = 0)
{
array[i] = false;
}
else if (array[i] = 1)
{
array[i] = true;
}
}
output.innerHTML = array;
}); //end document.ready
/*****
Purpose: Converts a character into ascii
Parameters: single character / letter
Return: integer representing an ascii value
*****/
function parseAscii(chrCharacter)
{
intAscii = chrCharacter.charCodeAt(0);
return intAscii;
}
/*****
Purpose: Takes the ascii code and turns it into binary
Parameters: single integer representing an ascii value
Return: binary, base 2 representation of the number passed to this function
*****/
function parseBin(intAscii)
{
strBin = parseInt(intAscii, 10).toString(2);
if(strBin.length < 8)
{
var intPlaceHolders = 8 - strBin.length;
for(var i = 0; i < intPlaceHolders; i++)
{
strBin = "0" + strBin;
}
}
return strBin;
}
I would convert the array with binaries to an array with boolean values wich you can joint together to a string that can be shown on the webpage.
array = [1,1,0,0,1]
// This will map over the items and perform an type conversion
var booleanArray = array.map(Boolean)
// Join all the items together as a string
Var booleanString = booleanArray.join(", ")
output.innerHTML = booleanString
`
I didn't test it, but it should work if I didn't make any typo's.
Btw, I dont think that this is what they ment with looping. But it's definitely a way to get the job done.
If I understand your question correctly, you can convert your array of ones and zeros (binary) to values of ture and false using the map function and using innerHTML to add the output to the DOM:
See example below:
// Populate myBinaryArray using your ascii method to get the follow:
let myBinaryArray = [1, 0, 0, 1, 1, 0, 1];
document.body.innerHTML += myBinaryArray.map(bit => !(!bit));

Generate CHAP response in java

Currently I'm trying to generate a chap response in java. It works in php... but our backend needs it done in java.
var challenge = "cda9af6faa83d0883d694fa58d2e88wh";
var password = "password123";
var hexchal = challenge.packHex();
var newchal = hexchal;
var response = md5('\0' + password + newchal)
I've managed to find some javascript code, but the response is off by a few characters.
function getPapPassword(){
//function to add value padding to a string of x length default : null padding
String.prototype.pad = function (length, padding) {
var padding = typeof padding === 'string' && padding.length > 0 ? padding[0] : '\x00'
, length = isNaN(length) ? 0 : ~~length;
return this.length < length ? this + Array(length - this.length + 1).join(padding) : this;
};
//function to convert hex to ascii characters
String.prototype.packHex = function () {
var source = this.length % 2 ? this + '0' : this
, result = '';
for (var i = 0; i < source.length; i = i + 2) {
result += String.fromCharCode(parseInt(source.substr(i, 2), 16));
}
return result;
};
var challenge = "cda9af6faa83d0883d694fa58d2e88wh";
var password = "password123";
var hexchal = challenge.packHex();
var newchal = hexchal;
var response = md5('\0' + password + newchal);
}
return response;
}
Can anyone point me in the right direction or assist?
Thanks
Okay so what I've done is tried to convert from hex to ascii in java... here is my code.
public class App{
public String convertHexToString(String hex){
StringBuilder sb = new StringBuilder();
StringBuilder temp = new StringBuilder();
//49204c6f7665204a617661 split into two characters 49, 20, 4c...
for( int i=0; i<hex.length()-1; i+=2 ){
//grab the hex in pairs
String output = hex.substring(i, (i + 2));
//convert hex to decimal
int decimal = Integer.parseInt(output, 16);
//convert the decimal to character
sb.append((char)decimal);
temp.append(decimal);
}
System.out.println("Decimal : " + temp.toString());
return sb.toString();
}
public static void main(String[] args) {
App app = new App();
System.out.println("ASCII : " + app.convertHexToString("9f9585f4e88305fde280c762925f37af"));
}
}
The php of the hex challenge output is: Ÿ•…ôèƒýâ€Çb’_7¯
The java output of the hex challenge is: ôèýâÇb_7¯
So I've found that the javascript is exactly the same as the java. Something is happening in php that is changing it. The php version works perfectly when I connect to the UAM with that chap response.

how to convert object to binary string

Here is how I compress binary string (char codes above 255) with pako:
var charData = xhr.responseText.split('').map(function(x){return x.charCodeAt(0);});
var binData = new Uint8Array(charData);
var data = pako.deflate(binData, {level:"9"});
Here is how I decompress data back:
var data2 = pako.inflate(xhr.responseText);
Now, how can I get original string in JavaScript from this object?
I tried methods like this:
A.
pako.inflate(xhr.responseText, {to:"string"});
B.
String.fromCharCode.apply(null, data2);
C.
for (var i = 0, l = data2.length; i < l; i++)
{
result += String.fromCharCode(parseInt(array[i], 2));
}
All of these methods bring different data as JavaScript string than original.
When I save decompressed pako.inflate(xhr.responseText) to a file (using functions with a.download) then dempressed file has exactly the same bytes as original file (so compression and decompression works correctly, without any byte modification).
I am just trying to do the same and found a way to convert Object to binary string and vice versa. I just create a two function that converts JSON Object to Binary String and Binary String to JSON Object viz. covertObjectToBinary and convertBinaryToObject.
let obj = {a:1}
function covertObjectToBinary(obj) {
let output = '',
input = JSON.stringify(obj) // convert the json to string.
// loop over the string and convert each charater to binary string.
for (i = 0; i < input.length; i++) {
output += input[i].charCodeAt(0).toString(2) + " ";
}
return output.trimEnd();
}
function convertBinaryToObject(str) {
var newBin = str.split(" ");
var binCode = [];
for (i = 0; i < newBin.length; i++) {
binCode.push(String.fromCharCode(parseInt(newBin[i], 2)));
}
let jsonString = binCode.join("");
return JSON.parse(jsonString)
}
console.log('covertObjectToBinary =>', covertObjectToBinary(obj))
console.log('convertBinaryToObject =>', convertBinaryToObject(covertObjectToBinary(obj)))

Address to WCHAR_T to pass to ReadProcessMemory

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.

Javascript fails to give correct output in IE

<script>
// This would be the place to edit if you want a different
// Base32 implementation
var alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ012345'
/**
* Build a lookup table and memoize it
*
* Return an object that maps a character to its
* byte value.
*/
var lookup = function() {
var table = {}
// Invert 'alphabet'
for (var i = 0; i < alphabet.length; i++) {
table[alphabet[i]] = i
}
lookup = function() { return table }
return table
}
// Functions analogously to Encoder
function Decoder() {
var skip = 0 // how many bits we have from the previous character
var byte = 0 // current byte we're producing
this.output = ''
// Consume a character from the stream, store
// the output in this.output. As before, better
// to use update().
this.readChar = function(char) {
if (typeof char != 'string'){
if (typeof char == 'number') {
char = String.fromCharCode(char)
}
}
//char = char.toLowerCase()
var val = lookup()[char]
if (typeof val == 'undefined') {
// character does not exist in our lookup table
return // skip silently. An alternative would be:
// throw Error('Could not find character "' + char + '" in lookup table.')
}
val <<= 3 // move to the high bits
byte |= val >>> skip
skip += 5
if (skip >= 8) {
// we have enough to preduce output
this.output += String.fromCharCode(byte)
skip -= 8
if (skip > 0) byte = (val << (5 - skip)) & 255
else byte = 0
}
}
this.finish = function(check) {
var output = this.output + (skip < 0 ? alphabet[bits >> 3] : '') + (check ? '$' : '')
this.output = ''
return output
}
}
Decoder.prototype.update = function(input, flush) {
for (var i = 0; i < input.length; i++) {
this.readChar(input[i])
}
var output = this.output
this.output = ''
if (flush) {
output += this.finish()
}
return output
}
/** Convenience functions
*
* These are the ones to use if you just have a string and
* want to convert it without dealing with streams and whatnot.
*/
// Base32-encoded string goes in, decoded data comes out.
function decode(input) {
var decoder = new Decoder()
var output = decoder.update(input.split("").reverse().join("")+'A', true)
return output
}
function toHex(str) {
var hex = '';
for(var i=0;i<str.length;i++) {
//hex += ''+("00" + str.charCodeAt(i).toString(16)).substr(-2);
hex += str.charCodeAt(i).toString(16);
}
return hex;
}
convertHex = toHex(decode('A0C4KB'));
alert(convertHex);
</script>
The above script works fine on FF and Chrome and gives me the correct hex value.
The alert output comes as expected with
abc2d0
For IE, this doesn't seem to work. I get all
ffffffff
This is a Base32 implementation that I pickep up from https://github.com/agnoster/base32-js
Internet Explorer's JScript engine doesn't support array access to string constants. You'll have to replace alphabet[i] with alphabet.charAt(i) to get it working. I thought MS had addressed this issue, though, but I could be wrong/too hopeful.

Categories