I have a variable of type BYTE*, in which an address from memory is: BYTE* address = (BYTE*)0x4A4B4C4D and a BYTE Array with 5 digits, where I want to copy the address exactly as it is. BYTE* jmp = new BYTE[5] {0xE9, 0x00, 0x00, 0x00, 0x00} This array is supposed to represent a 32 bit jump and I have to copy the address to the last 4 digits because it is 4 bytes large. I’ve tried memcpy before, but it seems like memcpy is only copying the bytes that are at that address in memory and that’s what I don’t want. So my goal is to have a byte array that looks like this: BYTE[5] {0xE9, 0x4A, 0x4B, 0x4C, 0x4D}.
Edit:
BYTE* jmp = new BYTE[5] {0xE9, 0x00, 0x00, 0x00, 0x00};
BYTE* address = (BYTE*)0x4A4B4C4D;
memcpy((jmp + 1), &address, 4);
delete[] jmp;
You're very "pointer-heavy".
BYTE jmp[5] = {0xE9};
uint32_t address = 0x4A4B4C4D;
memcpy(jmp + 1, &address, 4);
or, depending on endianness,
BYTE jmp[5] = {0xE9};
uint32_t address = 0x4D4C4B4A;
memcpy(jmp + 1, &address, 4);
So there's a couple problems here.
First of all, you are missing a 4 digit in your assignment to address, this is why you get a confusing 0xE9 0x4D 0xBC 0xA4 0x04
BYTE* address = (BYTE*)0x4A4B4C4D;
^
this was missing
The reason the byte ordering is changed when you do a memcpy is because endianness, read it up:
https://en.wikipedia.org/wiki/Endianness
In your case, it's little-endian.
Memcpy will just copy the memory content as-is. If you need the jmp to order the bytes in a different way, then the only way is to manually copy each byte across:
BYTE *ptr_address = (BYTE *)&address;
for(int i=0;i<4;i++)
{
jmp[1+i] = ptr_address[3-i];
}
I am having a problem with a school assignment. The assignment is to write a metamorphic Hello World program. This program will produce 10 .com files that print "Hello World!" when executed. Each of the 10 .com files must be different from the others. I understand the concept of metamorphic vs oligomorphic vs polymorphic. My program currently creates 10 .com files and then writes the machine code to the files. I began by simply writing only the machine code to print hello world and tested it. It worked just fine. I then tried to add a decryption routine to the beginning of the machine code. Here is my current byte array:
#define ARRAY_SIZE(array) (sizeof((array))/sizeof((array[0])))
BYTE pushCS = 0x0E;
BYTE popDS = 0x1F;
BYTE movDX = 0xBA;
BYTE helloAddr1 = 0x1A;
BYTE helloAddr2 = 0x01;
BYTE movAH = 0xB4;
BYTE nine = 0x09;
BYTE Int = 0xCD;
BYTE tOne = 0x21;
BYTE movAX = 0xB8;
BYTE ret1 = 0x01;
BYTE ret2 = 0x4C;
BYTE movBL = 0xB3;
BYTE keyVal = 0x03; // Encrypt/Decrypt key
typedef unsigned char BYTE;
BYTE data[] = { 0x8D, 0x0E, 0x01, 0xB7, 0x1D, 0xB3, keyVal, 0x30, 0x1C, 0x46, 0xFE, 0xCF, 0x75, 0xF9,
movDX, helloAddr1, helloAddr2, movAH, nine, Int, tOne, movAX, ret1, ret2, Int, tOne,
0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0D, 0x0D, 0x0A, 0x24 };
The decryption portion of the machine code is the first 14 bytes of "data". This decryption routine would take the obfuscated machine code bytes and decrypt them by xor-ing the bytes with the same key that was used to encrypt them. I am encrypting the bytes in my C++ code with this:
for (int i = 15; i < ARRAY_SIZE(data); i++)
{
data[i] ^= keyVal;
}
I have verified over and over again that my addressing is correct considering that the code begins at offset 100. What I have noticed is that when keyVal is 0x00, my code runs fine and I get 10 .com files that print Hello World!. However, this does me no good as 0x00 leaves everything unchanged. When I provide an actual key like 0x02, my program no longer works. It simply hangs until I close out DosBox. Any hints as to the cause of this would be a great help. I have some interesting plans for junk insertion (The actual metamorphic part) but I don't want to move on to that until I figure out this encrypt/decrypt issue.
The decryption portion of the machine code is the first 14 bytes of "data".
and
for (int i = 15; i < ARRAY_SIZE(data); i++)
do not match since in C++ array indexes start at 0.
In your array data[15] == helloAddr1 which means you are not encrypting the data[14] == movDX element. Double-check which elements should be encrypted and start at i = 14 if required.
I am using the Wire class to have two Arduino Unos communicate using I2C. It seems that the Wire class ends transmission on a value of 0. So if I send bytes 0x01, 0x02, 0x00, and 0x04, the master receives: 0x01, 0x02, 0xFF, 0xFF.
It seems odd that a communication network designed for processor communication cannot send a 0x00. All the examples for I2C that I have seen use ASCII only. Inter-processor communication restricted to ASCII does not seem to make any sense. Am I missing something with I2C or is this just an implementation limitation of the Arduino Wire class?
Master
void loop() {
Wire.requestFrom(2, 4);
while(Wire.available()) {
byte b = (byte) Wire.read();
Serial.println(b);
}
delay(1000);
}
Slave
void requestEvent() {
char bytes[4] = {0x01,0x02,0x00,0x04};
Wire.write(bytes);
}
The results are: 1 2 255 255.
When that 0x00 was 0x03 I got the expected: 1 2 3 4.
You are passing an array of chars to Wire.write()... This makes Wire treat the argument as a null-terminated string, and therefore the NULL byte terminates the transmission. If you want to send bytes, call the write() function once for each byte, passing it byte types.
Alternatively, you can call the write(const uint8_t *, size_t); version: you pass it a pointer to / array of bytes, but you also have to give it a size of your data array.
Do you have Wire.begin() and Wire.beginTransmission() (with correct address) happening before calling Wire.write()?
#include<iostream>
#define check_bit(var,pos) {return (var & (1 << pos))!=0;}
using namespace std;
int main()
{
uint8_t temp[150]={0x00,0x02,0x17,0xe2,0x1c,0xa8,0x00,0x30,0x96,0xe1,0x8c, 0x38,
0x88, 0x47, 0x00 ,0x01 ,
0x30, 0xfe, 0x00, 0x01 ,0x31, 0xfe, 0x45, 0x00, 0x00 ,0x64, 0x3b, 0x89 ,0x00, 0
x00 ,0xfe, 0x01 ,
0x33, 0x5a, 0xc0 ,0xa8 ,0x79 ,0x02 ,0x0a, 0x0a, 0x0a, 0x01, 0x08, 0x00, 0xe3, 0
x86, 0x00, 0xea,
0x01, 0xd2, 0x00, 0x00, 0x00, 0x05, 0x02, 0x6a, 0x95 ,0x98, 0xab ,0xcd ,0xab, 0x
cd ,0xab, 0xcd,
0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd ,0xab, 0xcd ,0xab ,0
xcd ,0xab, 0xcd,
0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd ,0xab ,0xcd ,0xab ,0
xcd, 0xab ,0xcd,
0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd , 0xab, 0xcd ,0xab, 0xcd, 0xab, 0
xcd, 0xab ,0xcd,
0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd, 0xab, 0xcd , 0xab, 0xcd
};
uint16_t *ptr1=(uint16_t*)&temp[0];
while(!(*(ptr1+0)==0x88 && *(ptr1+1)==0x47))
{
ptr1++;
}
cout<<"MPLS packet";
uint32_t *ptr2=(uint32_t*)&temp[0];
cout<<"4 bytes accessed at a time";
ptr2++;
while(check_bit(*(ptr+3),7)!=1)
{
cout<<"bottom of the stack:label 0";
ptr2++;
}
cout<<"mpls label:1";
return 0;
}
The program is intended to identify packet is MPLS or not by accessing two bytes at a time and checking presence of 88 and 47 packets and if MPLS packet then it should access four packets at a time and check 3rd byte(30 in this case) is enabled or not.If not enabled then access next four bytes and check byte is enabled or not.I have written program but it is not working.Please someone help me.I am not able to access individual element of array.if i give cout<<temp[0] it gives garbage value
Please help
First thing I noticed is that your code looks for consecutive 16-bit values of 0x88 and 0x47, but in the packet itself these values seem to be 8-bit (1 byte each). If ptr1 is changed to be uint8_t*, it will be able to find the values. I don't know what the correct behavior for the rest of the code is so I can't check it.
In general, directly reading values that are bigger than 8 bits (e.g. uint16_t or uint32_t) from memory here may not be a good idea because your program will behave differently on little-endian and big-endian processors. And as ydroneaud mentions in a comment, some processors won't be able to read these values because you read them from unaligned addresses.
I think I can fix your program, but you better listen to the other folks who know networking stuff better than myself.
uint8_t *ptr=temp;
while(ptr[0]!=0x88 || ptr[1]!=0x47)
{
ptr++;
}
cout<<"MPLS packet";
ptr+=2;
cout<<"4 bytes accessed at a time";
while(!check_bit(ptr[2],7))
{
cout<<"bottom of the stack:label 0";
ptr+=4;
}
cout<<"mpls label:1";
return 0;
Edit: to print individual bytes from the array you need to cast them to some integer type first. This is because uint8_t is most likely typedeffed as unsigned char which is interpreted by cout as a character code. Then you need to set the cout to hexadecimal mode:
cout << hex << (int)ptr[2] << endl;
Edit 2: there is an error in your check_bit() macro. A macro is not a function, but a piece of text that is copied as is (replacing the arguments) in place where its name is mentioned. It must be
#define check_bit(var,pos) (((var)&(1<<(pos)))!=0)
or define a function instead:
bool check_bit(int var, int pos) {return (var & (1 << pos))!=0;}
A little bit more worked out version of my comment: You should actually decode the network stack to be sure if MPLS is present, the 0x8847 value is not extremely unlikely to occur somewhere in payload, addressing schemes, ... .
To actually get to this you should decode the network stack. Lets assume you begin with an ethernet frame. Note first that most applications will give you data from the destination mac address onwards, preambles and such are discarded. So the 13th and 14th byte are the type field. This tells you what is encapsulated in ethernet, this is usually 0x0800 meaning IP. 0x8847 means a unicast static MPLS label. Other options are possible, for example ipv6 or vlan tags (described below). But note you can determine with certainty which offsets you use. You know what is encapsulated in the mac frame and where this encapsulated data starts (15th octet). Of course you see there are optional q-tags there, I explain these below.
Now as You are looking for 0x8847 I guess you have direct MPLS over ethernet, in which case you shouldn't go any further, but if your stack is more complex you'll have to decode also the next encapsulated data (e.g. IP) and take into account these sizes up until the point where you can find your MPLS header.
For ethernet there are 2 somewhat common options and that are dot1q and qinq tagging, or vlan tags. dot1q adds 4 bytes to the ethernet header, you can recognise this because the type field will be 0x8100, in this case the real type field (of what is encapsulated) will be 4 bytes further one (so the 17th byte) and the encapsulated data will start on the 19th byte. With qinq the type will be 0x9100 and the real type will be 8 bytes further on, so the 21th byte, the encapsulated data can be found from the 23rd byte onwards.
Of course, decoding the whole network stack implementation would be crazy. To start with you can ignore addressing, QoS, ... . You mostly need to find what is the type to the next header and where this starts (this can be influenced by optional fields like dot1q). Usually you know beforehand which kind of stack you have on your system. So it involves studying these headers and finding the fixed offset where you can find your MPLS header, which makes the work quite simple.
I have a structure:
struct JFIF_HEADER
{
WORD marker[2]; // = 0xFFD8FFE0
WORD length; // = 0x0010
BYTE signature[5]; // = "JFIF\0"
BYTE versionhi; // = 1
BYTE versionlo; // = 1
BYTE xyunits; // = 0
WORD xdensity; // = 1
WORD ydensity; // = 1
BYTE thumbnwidth; // = 0
BYTE thumbnheight; // = 0
};
This is how I read it from the file:
HANDLE file = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
DWORD tmp = 0;
DWORD size = GetFileSize(file, &tmp);
BYTE *DATA = new BYTE[size];
ReadFile(file, DATA, size, &tmp, 0);
JFIF_HEADER header;
memcpy(&header, DATA, sizeof(JFIF_HEADER));
This is how the beginning of my file looks in hex editor:
0xFF 0xD8 0xFF 0xE0 0x00 0x10 0x4A 0x46 0x49 0x46 0x00 0x01 0x01 0x00 0x00 0x01
When I print header.marker, it shows exactly what it should (0xFFD8FFE0). But when I print header.length, it shows 0x1000 instead of 0x0010. The same thing is with xdensity and ydensity. Why do I get wrong data when reading a WORD?
You are on an x86 cpu which stores words low byte-high byte (little endian)
The binary file is presumably stored in big endian.
You need to manually swap each byte in the file (or possibly your JFIF library will do this for you)
ps. The safest way to swap bytes is to use the ntohs() and htons() macros in your 'C' library.
See the wiki article for the details of endianness