구조체 주소에 액세스 할 수 있으면 적어도 시작을 위해 거기에있는 것의 바이트 덤프. '
이
first x:
Byte offset: (nil) Byte: 0x68 Ascii: h
Byte offset: 0x1 Byte: 0x69 Ascii: i
Byte offset: 0x2 Byte: 0xF3 Ascii:
Byte offset: 0x3 Byte: 0xB7 Ascii: �
Byte offset: 0x4 Byte: 0x19 Ascii:
Byte offset: 0x5 Byte: 0x00 Ascii:
Byte offset: 0x6 Byte: 0x00 Ascii:
Byte offset: 0x7 Byte: 0x00 Ascii:
Byte offset: 0x8 Byte: 0xC3 Ascii:
Byte offset: 0x9 Byte: 0xF5 Ascii:
Byte offset: 0xa Byte: 0x48 Ascii: H
Byte offset: 0xb Byte: 0x40 Ascii: @
Byte offset: 0xc Byte: 0xD8 Ascii:
Byte offset: 0xd Byte: 0x85 Ascii: �
Byte offset: 0xe Byte: 0x04 Ascii:
Byte offset: 0xf Byte: 0x08 Ascii:
second x:
Byte offset: (nil) Byte: 0x6F Ascii: o
Byte offset: 0x1 Byte: 0x6C Ascii: l
Byte offset: 0x2 Byte: 0xF3 Ascii:
Byte offset: 0x3 Byte: 0xB7 Ascii: �
Byte offset: 0x4 Byte: 0xFF Ascii: �
Byte offset: 0x5 Byte: 0x00 Ascii:
Byte offset: 0x6 Byte: 0x00 Ascii:
Byte offset: 0x7 Byte: 0x00 Ascii:
Byte offset: 0x8 Byte: 0x00 Ascii:
Byte offset: 0x9 Byte: 0x00 Ascii:
Byte offset: 0xa Byte: 0x10 Ascii:
Byte offset: 0xb Byte: 0xC1 Ascii:
Byte offset: 0xc Byte: 0xE7 Ascii:
Byte offset: 0xd Byte: 0x85 Ascii: �
Byte offset: 0xe Byte: 0x04 Ascii:
Byte offset: 0xf Byte: 0x08 Ascii:
내가 사용 가정하면 입력 데이터로 무엇을 알고, 당신은 단지 돈 : 여기에 내가 만든 5 분 해킹 :
#include <stdio.h>
typedef struct {
char c1;
char c2;
int i;
float f;
char *str;
} unknown;
void decode(unsigned char *address, int len) {
unsigned char *p = address;
for (; p < address + len ; p++) {
printf("Byte offset: %p\tByte: 0x%02X\tAscii: %c\n", p - address, *p, *p);
}
}
int main() {
unknown x;
int len = sizeof(unknown); /* or 13 like you've said the size is */
/* this would happen in whatever software
you're using to generate the struct */
x.c1 = 'h';
x.c2 = 'i';
x.i = 25;
x.f = 3.14;
x.str = "Hello";
printf("first x:\n");
decode((unsigned char*)(&x), len);
x.c1 = 'o';
x.c2 = 'l';
x.i = 255;
x.f = -9;
x.str = "Goodbye";
printf("second x:\n");
decode((unsigned char*)(&x), len);
return 0;
}
는 그리고 여기에 출력의 레이아웃이 무엇인지, 또는 레이아웃에 무엇이 포함되어 있는지를 안다.
우리는 거기에 무엇이 있는지를 알기조차 어렵습니다. char
은 해독하기가 가장 쉽습니다. 우리는 처음에는 '안녕'에서 '올'로 바뀌 었음을 알 수 있습니다.
다음은 int이며, 25에서 255로 변경됩니다. 오프셋 0x4에서 0x19와 0xff의 두 값을 볼 수 있지만 나머지 바이트는 어디에 있습니까? 0x5-0x7입니까? (int가 "거꾸로"저장되어 있다고 제안 하시겠습니까?) 아마 0x2-0x3 오프셋은 우리가 사용한 1 바이트 문자 (C 구조체는 워드 크기에 따라 정렬 됨)를 채우기위한 것일뿐입니다.
그렇다면 float가 있습니다. 실제로 플로트가 내부적으로 어떻게 인코딩되는지 모르므로 차이점을 추론하려고하지는 않습니다. 아마도 IEEE 표준을 찾아 볼 수 있습니다.
마지막으로 포인터로 닫습니다. 해당 구조체에 포인터가 있으면 프로그램을 segfault하지 않고 해당 메모리 주소를 찾아 봐야합니다. 그것들은 다른 구조체에 대한 포인터 일 수 있습니다.이 경우이 프로세스를 반복하는 기쁨을 누릴 수 있습니다.
내가 말했듯이, 이것은 내 5 분 걸릴 것이고, 실제로 전에 이것을 시도한 적이 없습니다. 이것은 여러분이 이것에 대해 어떻게 생각하는지에 대한 첫 번째 추측이었습니다. 알려진 입력으로 시작한 다음 구조체에 저장된 데이터 형식과 해당 바이트 오프셋을 확인할 때까지 한 번에 한 가지만 변경하십시오.
나는 그것에 총을 맞았고, 좋지 않다. 타임 스탬프처럼 보이는 8 바이트가 있습니다. 그들은 실제로 C 시간 구조를 따르지 않습니다. 다른 데이터 형식으로 deserialized했습니다 있지만 값 사이의 간격을 일렬로 것 같습니다. 해시 결과 또는 체크섬 일 수 있다고 생각하기 시작했습니다. 이 경우 잊어 버려. 글쎄, 그것은 총 손실 아니에요. DirectX, 메모리의 구조 레이아웃 및 비 직렬화에 대해 배웠습니다. – Patrick
얼마 동안 이것을 선반에 얹은 후에, 나는 최근에 더 많은 성공을 거두었습니다. 이전에 프로그램간에 전송 된 첫 번째 패킷 만보고 실수를 저질렀습니다. 이번에는 MS NetMon을 설정하고 몇 분의 데이터를 캡처했습니다. NetMon API를 사용하여 데이터를 눈으로 볼 필요없이 프로그래밍 방식으로 패턴을 찾습니다. 또한 BitConverter 클래스를 사용하여 전체 내용을 비 직렬화하는 대신 바이트 배열에서 개별 필드를 뽑았습니다. 나는 지금 찾고있는 분야의 절반 정도를 가지고있다. C#의 샘플 NetMon API 코드 : [Top Users] (http://nmtopusers.codeplex.com) – Patrick