/** @brief 해당하는 버퍼가 유효한 청크 헤더 인지 확인한다 @param arg 메모리 버퍼 @return 유효성 여부 */ bool EvtxChunkValidator::isValidChunkHeader(void* arg) { EVTX_CHUNK_HEADER* chunkHeader = (EVTX_CHUNK_HEADER*)arg; uint8_t* chunkData = (uint8_t*)arg; uint32_t headerCrc = 0; if (chunkHeader->magic != EVTX_CHUNK_HEADER_MAGIC) return false; headerCrc = update_crc32(0, chunkData, 0x78); headerCrc = update_crc32(headerCrc, chunkData + 0x80, 0x180); // 청크 헤더의 crc유효성 확인 if (headerCrc != chunkHeader->headerCRC) { return false; } // 비어있는 청크는 유효하지 않다고 가정 if (chunkHeader->numLogRecFirst == 1 && chunkHeader->numLogRecLast == 0xFFFFFFFFFFFFFFFFll) { return false; } return true; }
/** @brief 해당하는 버퍼가 유효한 청크인지 확인한다 @param arg 메모리 버퍼 @return 유효성 여부 */ bool EvtxChunkValidator::isValidChunk(void* arg) { EVTX_CHUNK_HEADER* chunkHeader = (EVTX_CHUNK_HEADER*)arg; uint8_t* chunkData = (uint8_t*)arg; uint32_t headerCrc = 0; uint32_t dataCrc = 0; if (chunkHeader->magic != EVTX_CHUNK_HEADER_MAGIC) { return false; } headerCrc = update_crc32(0, chunkData, 0x78); headerCrc = update_crc32(headerCrc, chunkData + 0x80, 0x180); // 청크헤더의 crc유효성 여부 확인 if (headerCrc != chunkHeader->headerCRC) { return false; } // 비어있는 청크는 유효하지 않다고 가정 if (chunkHeader->numLogRecFirst == 1 && chunkHeader->numLogRecLast == 0xFFFFFFFFFFFFFFFFll) { return false; } dataCrc = update_crc32(0, chunkData + EVTX_CHUNK_HEADER_SIZE, chunkHeader->ofsRecNext - EVTX_CHUNK_HEADER_SIZE); // 청크 데이터의 crc유효성 여부 확인 return dataCrc == chunkHeader->dataCRC; }
int main(void) { setup_data(); int n = *init_n; #if 0 unsigned long crc_table[256]; make_crc32_table(crc_table); #else #include "crc32table.c" #endif printf("mm n=%d\n", n); int *a = malloc(0x100000); int *b = malloc(0x100000); int *c = malloc(0x100000); assert(a != NULL && b != NULL && c != NULL); int y,x,i; /* ----- Initialize ----- */ #if 1 int d = 0; for (i = 0; i < n*n; i += 4) { int v0, v1, v2, v3, v4, v5, v6, v7; v0 = init_data[d ]; v1 = init_data[d+1]; v2 = init_data[d+2]; v3 = init_data[d+3]; v4 = init_data[d+4]; v5 = init_data[d+5]; v6 = init_data[d+6]; v7 = init_data[d+7]; a[i] = v0; b[i] = v1; a[i+1] = v2; b[i+1] = v3; a[i+2] = v4; b[i+2] = v5; a[i+3] = v6; b[i+3] = v7; c[i] = 0; c[i+1] = 0; c[i+2] = 0; c[i+3] = 0; d = (d + 8) % (64*1024); } #else int d = 0; for(y=0; y<n; y++) { for(x=0; x<n; x++) { a[n*y+x] = init_data[d % (64*1024)]; b[n*y+x] = init_data[(d+1) % (64*1024)]; c[n*y+x] = 0; d +=2; } } #endif /* ----- main kernel ----- */ #if 1 static int mm[4][4]; for(y = 0; y < n; y += 4) { for(x = 0; x < n; x += 4) { int ix, iy; /* clear temporary sub-matrix */ for (iy = 0; iy < 4; iy++) for (ix = 0; ix < 4; ix++) mm[iy][ix] = 0; /* calc 4x4 sub-matrix */ for (i = 0; i < n; i++) { #if 1 int v0, v1, v2, v3; v0 = a[n*(y+0) + i]; v1 = a[n*(y+1) + i]; v2 = a[n*(y+2) + i]; v3 = a[n*(y+3) + i]; mm[0][0] += v0 * b[n*i + x+0]; mm[0][1] += v0 * b[n*i + x+1]; mm[0][2] += v0 * b[n*i + x+2]; mm[0][3] += v0 * b[n*i + x+3]; mm[1][0] += v1 * b[n*i + x+0]; mm[1][1] += v1 * b[n*i + x+1]; mm[1][2] += v1 * b[n*i + x+2]; mm[1][3] += v1 * b[n*i + x+3]; mm[2][0] += v2 * b[n*i + x+0]; mm[2][1] += v2 * b[n*i + x+1]; mm[2][2] += v2 * b[n*i + x+2]; mm[2][3] += v2 * b[n*i + x+3]; mm[3][0] += v3 * b[n*i + x+0]; mm[3][1] += v3 * b[n*i + x+1]; mm[3][2] += v3 * b[n*i + x+2]; mm[3][3] += v3 * b[n*i + x+3]; #else for (iy = 0; iy < 4; iy++) for (ix = 0; ix < 4; ix++) mm[iy][ix] += a[n*(y+iy) + i] * b[n*i + x+ix]; #endif } /* write temporary sub-matrix to main-matrix */ for (iy = 0; iy < 4; iy++) for (ix = 0; ix < 4; ix++) c[n*(y+iy) + (x+ix)] = mm[iy][ix]; } } /* for(y = 0; y < n; y++) { for(x = 0; x < n; x++) { int s = 0; for(i = 0; i < n; i++) s += a[n*y+i] * b[n*i+x]; c[n*y+x] = s; } } */ #else for(y = 0; y < n; y++) { for(x = 0; x < n; x++) { for(i = 0; i < n; i++) { c[n*y+x] += a[n*y+i] * b[n*i+x]; } } } #endif /* ----- show result ----- */ printf("\n"); #if 1 for(y = n-8; y<n; y++) { int v0, v1, v2, v3, v4, v5, v6, v7; int *p = &c[n*y + n-8]; v0 = *(p + 0); v1 = *(p + 1); v2 = *(p + 2); v3 = *(p + 3); v4 = *(p + 4); v5 = *(p + 5); v6 = *(p + 6); v7 = *(p + 7); printf("%08x %08x %08x %08x ", v0, v1, v2, v3); printf("%08x %08x %08x %08x ", v4, v5, v6, v7); printf("\n"); } #else for(y = n-8; y<n; y++) { for(x = n-8; x<n; x++) { printf("%08x ", c[n*y+x]); } printf("\n"); } #endif unsigned long sum = 0; for(y = 0; y < n; y++) { for(x = 0; x < n; x++) { //sum += c[n*y+x]; sum = update_crc32(sum, c[n*y+x], crc_table); } } printf("%08lx\n", sum); return 0; }
// returns: ERROR_OK, ERROR_INPUTOUPUT, ERROR_INTEGRITY void extractDataToFile(LauncherProperties * props, WCHAR *output, int64t * fileSize, DWORD expectedCRC ) { if(isOK(props)) { DWORD * status = & props->status; HANDLE hFileRead = props->handler; int64t * size = fileSize; DWORD counter = 0; DWORD crc32 = -1L; HANDLE hFileWrite = CreateFileW(output, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, hFileRead); if (hFileWrite == INVALID_HANDLE_VALUE) { WCHAR * err; writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "[ERROR] Can`t create file ", 0); writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, output, 1); err = getErrorDescription(GetLastError()); writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Error description : ", 0); writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, err, 1); showErrorW(props, OUTPUT_ERROR_PROP, 2, output, err); FREE(err); *status = ERROR_INPUTOUPUT; return; } if(props->restOfBytes->length!=0 && props->restOfBytes->bytes!=NULL) { //check if the data stored in restBytes is more than we neen // rest bytes contains much less than int64t so we operate here only bith low bits of size DWORD restBytesToWrite = (compare(size, props->restOfBytes->length)> 0 ) ? props->restOfBytes->length : size->Low; DWORD usedBytes = restBytesToWrite; char *ptr = props->restOfBytes->bytes; DWORD write = 0; while (restBytesToWrite >0) { WriteFile(hFileWrite, ptr, restBytesToWrite, &write, 0); update_crc32(&crc32, ptr, write); restBytesToWrite -= write; ptr +=write; } modifyRestBytes(props->restOfBytes, usedBytes); minus(size, usedBytes); } if(compare(size, 0) > 0 ) { DWORD bufferSize = props->bufsize; char * buf = newpChar(bufferSize); DWORD bufsize = (compare(size, bufferSize) > 0) ? bufferSize : size->Low; DWORD read = 0 ; // printf("Using buffer size: %u/%u\n", bufsize, bufferSize); while (ReadFile(hFileRead, buf, bufsize, &read, 0) && read && compare(size, 0) > 0) { addProgressPosition(props, read); WriteFile(hFileWrite, buf, read, &read, 0); update_crc32(&crc32, buf, read); minus(size, read); if((compare(size, bufsize)<0) && (compare(size, 0)>0) ) { bufsize = size->Low; } ZERO(buf, sizeof(char) * bufferSize); if(compare(size, 0)==0) { break; } if((counter ++) % 20 == 0) { if(isTerminated(props)) break; } } if((compare(size, 0)>0 || read==0) && !isTerminated(props)) { // we could not read requested size * status = ERROR_INTEGRITY; writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "Can`t read data from file : not enought data", 1); } FREE(buf); } CloseHandle(hFileWrite); crc32=~crc32; if(isOK(props) && crc32!=expectedCRC) { writeDWORD(props, OUTPUT_LEVEL_DEBUG, 0, "expected CRC : ", expectedCRC, 1); writeDWORD(props, OUTPUT_LEVEL_DEBUG, 0, "real CRC : ", crc32, 1); * status = ERROR_INTEGRITY; } } }
/** @brief 파일로부터 레코드의 정보들을 모은다 @param inRecordCarvedAreas 스킵할 영역 @param outRecordInfoMap 클러스터 번호 / 레코드정보 쌍으로 된 맵 @param outClustersHaveRecord 레코드를 가지고 있는 클러스터들 */ void ClusterReassembler::buildRecordInfoMap(CarvedAreas& inCarvedAreas, RecordInfoMap& outRecordInfoMap, stdext::hash_set<uint64_t>& outClustersHaveRecord) { SignatureFinder recordHeaderFinder(fragmentedFile_, EVTX_RECORD_HEADER_MAGIC, 4, 8, &inCarvedAreas, EVTX_RECORD_HEADER_SIZE); uint8_t* recordBuffer = NULL; EVTX_RECORD_HEADER* evtxRecordHeader = NULL; uint64_t foundFilePos = 0; uint64_t clusterNumber = 0; uint32_t clusterCrc = 0; uint8_t clusterBuffer[CLUSTER_SIZE] = {0,}; uint32_t clusterIndex = 0; outClustersHaveRecord.clear(); while ((recordBuffer = recordHeaderFinder.getNext(&foundFilePos)) != NULL) { evtxRecordHeader = (EVTX_RECORD_HEADER*)recordBuffer; if (EvtxRecordValidator::isValidRecordHeader(recordBuffer)) { clusterNumber = foundFilePos / CLUSTER_SIZE; fragmentedFile_.readData(clusterNumber * CLUSTER_SIZE, clusterBuffer, CLUSTER_SIZE); clusterCrc = update_crc32(0, clusterBuffer, CLUSTER_SIZE); if (outClustersHaveRecord.find(clusterNumber) == outClustersHaveRecord.end()) { outClustersHaveRecord.insert(clusterNumber); } // 레코드와 클러스터를 매핑중 중복된 레코드 아이디가 있으면 if (outRecordInfoMap.find(evtxRecordHeader->numLogRecord) != outRecordInfoMap.end()) { bool crcFound = false; // 클러스터의 crc를 비교하여 없는 crc이면 해당 클러스터를 레코드 아이디의 클러스터 후보군에 추가 for (clusterIndex = 0; clusterIndex < outRecordInfoMap[evtxRecordHeader->numLogRecord].size(); ++clusterIndex) { if (outRecordInfoMap[evtxRecordHeader->numLogRecord][clusterIndex].clusterCrc == clusterCrc) { crcFound = true; break; } } if (!crcFound) { outRecordInfoMap[evtxRecordHeader->numLogRecord].push_back(CLUSTER_INFO(clusterNumber, clusterCrc)); } } else { std::vector<CLUSTER_INFO> clusterInfos; clusterInfos.push_back(CLUSTER_INFO(clusterNumber, clusterCrc)); outRecordInfoMap[evtxRecordHeader->numLogRecord] = clusterInfos; } } } recordHeaderFinder.closeMap(); }