static void * execute_cfa_insn (void *p, struct frame_state_internal *state, struct cie_info *info, void **pc) { unsigned insn = *(unsigned char *)p++; unsigned reg; int offset; if (insn & DW_CFA_advance_loc) *pc += ((insn & 0x3f) * info->code_align); else if (insn & DW_CFA_offset) { reg = (insn & 0x3f); p = decode_uleb128 (p, &offset); offset *= info->data_align; state->s.saved[reg] = REG_SAVED_OFFSET; state->s.reg_or_offset[reg] = offset; } else if (insn & DW_CFA_restore) { reg = (insn & 0x3f); state->s.saved[reg] = REG_UNSAVED; } else switch (insn) { case DW_CFA_set_loc: *pc = read_pointer (p); p += sizeof (void *); break; case DW_CFA_advance_loc1: *pc += read_1byte (p); p += 1; break; case DW_CFA_advance_loc2: *pc += read_2byte (p); p += 2; break; case DW_CFA_advance_loc4: *pc += read_4byte (p); p += 4; break; case DW_CFA_offset_extended: p = decode_uleb128 (p, ®); p = decode_uleb128 (p, &offset); offset *= info->data_align; state->s.saved[reg] = REG_SAVED_OFFSET; state->s.reg_or_offset[reg] = offset; break; case DW_CFA_restore_extended: p = decode_uleb128 (p, ®); state->s.saved[reg] = REG_UNSAVED; break; case DW_CFA_undefined: case DW_CFA_same_value: case DW_CFA_nop: break; case DW_CFA_register: { unsigned reg2; p = decode_uleb128 (p, ®); p = decode_uleb128 (p, ®2); state->s.saved[reg] = REG_SAVED_REG; state->s.reg_or_offset[reg] = reg2; } break; case DW_CFA_def_cfa: p = decode_uleb128 (p, ®); p = decode_uleb128 (p, &offset); state->s.cfa_reg = reg; state->s.cfa_offset = offset; break; case DW_CFA_def_cfa_register: p = decode_uleb128 (p, ®); state->s.cfa_reg = reg; break; case DW_CFA_def_cfa_offset: p = decode_uleb128 (p, &offset); state->s.cfa_offset = offset; break; case DW_CFA_remember_state: { struct frame_state_internal *save = (struct frame_state_internal *) malloc (sizeof (struct frame_state_internal)); memcpy (save, state, sizeof (struct frame_state_internal)); state->saved_state = save; } break; case DW_CFA_restore_state: { struct frame_state_internal *save = state->saved_state; memcpy (state, save, sizeof (struct frame_state_internal)); free (save); } break; /* FIXME: Hardcoded for SPARC register window configuration. */ case DW_CFA_GNU_window_save: for (reg = 16; reg < 32; ++reg) { state->s.saved[reg] = REG_SAVED_OFFSET; state->s.reg_or_offset[reg] = (reg - 16) * sizeof (void *); } break; case DW_CFA_GNU_args_size: p = decode_uleb128 (p, &offset); state->s.args_size = offset; break; default: abort (); } return p; }
void load_appended_data() { BOOL bFlag; DWORD dwFileSize; wchar_t exe_name[MAX_PATH+1]; HANDLE hMapFile; HANDLE hFile; LPVOID lpMapAddress; const unsigned char *start; const unsigned char *end; const unsigned char *stringtab; unsigned int n_env; unsigned int i; shim_data *data; if (!GetModuleFileNameW(NULL, exe_name, MAX_PATH)) { error(RC_LOAD_DATA, L"Could not get executable name"); } hFile = CreateFileW(exe_name, GENERIC_READ, /* Let everyone else at the file, e.g., antivirus? */ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { error(RC_LOAD_DATA, L"Could not open executable %d", GetLastError()); } dwFileSize = GetFileSize(hFile, NULL); if (dwFileSize == 0) { error(RC_LOAD_DATA, L"Executable appears to be 0 bytes long"); } hMapFile = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (hMapFile == NULL) { error(RC_LOAD_DATA, L"Mapping the file failed - error %d", GetLastError()); } lpMapAddress = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); if (lpMapAddress == NULL) { error(RC_LOAD_DATA, L"Mapping the view failed - error %d", GetLastError()); } /* Get the appended data. Format is: * * XXXX....XXXX Data block (see below) * XXXX....XXXX Character data table, all strings are encoded as UTF-16LE and null terminated. * XXXX Offset of the start of the character data from the appended data start. * XXXX Length of appended data. */ end = ((const char *)lpMapAddress) + dwFileSize; start = end - read_4byte(end-4); stringtab = start + read_4byte(end-8); /* Data block format: * * 0 XXXX Marker - "SHIM" * 4 XXXX Type of base relative (0 = pathname, 1 = exe on PATH, 2 = env var, 3 = registry) * 8 XXXX Offset of exe name in string table * 12 XXXX Offset of base for relative exe in string table (0xFFFFFFFF means "exe name is absolute") * 16 XXXX Offset of cwd in string table (0xFFFFFFFF means "don't set CWD") * 20 XXXX Number of environment variable entries * n times: * 24 + 8*n XXXX Offset of env var name in string table * 28 + 8*n XXXX Offset of env var value in string table (0xFFFFFFFF means "Remove") */ /* Check for marker */ if (memcmp(start, "SHIM", 4) != 0) { error(RC_LOAD_DATA, L"Data block does not start with correct marker"); } n_env = read_4byte(start + 20); data = (shim_data *)malloc(sizeof(shim_data) + n_env * sizeof(kv)); if (data == NULL) { error(RC_NOT_ENOUGH_MEM, L"Not enough memory for shim data"); } data->exe_type = read_4byte(start + 4); data->exe = read_string(start + 8, stringtab); data->base = read_string(start + 12, stringtab); data->cwd = read_string(start + 16, stringtab); for (i = 0; i < n_env; ++i) { data->env[i].key = read_string(start + 24 + 8 * i, stringtab); data->env[i].value = read_string(start + 28 + 8 * i, stringtab); } data->env[n_env].key = 0; data->env[n_env].value = 0; bFlag = UnmapViewOfFile(lpMapAddress); bFlag = CloseHandle(hMapFile); bFlag = CloseHandle(hFile); if(!bFlag) { // Error occurred - do we report it? } }
static bool read_layer( FILE* fp, PsdLayerData* pLayerData) { int j; pLayerData->rect.top = read_4byte_BE(fp); pLayerData->rect.left = read_4byte_BE(fp); pLayerData->rect.bottom = read_4byte_BE(fp); pLayerData->rect.right = read_4byte_BE(fp); pLayerData->channel_num = read_2byte_BE(fp); pLayerData->psd_channels = (PsdChannel*) malloc(sizeof(PsdChannel) * pLayerData->channel_num); for(j=0; j<pLayerData->channel_num; j++){ pLayerData->psd_channels[j].id = read_2byte_BE(fp); pLayerData->psd_channels[j].data_length = read_4byte_BE(fp); } char mode_key[4]; if(!fread(mode_key, 4, 1, fp)){ return false; } if(memcmp(mode_key, "8BIM", 4) != 0){ return false; } pLayerData->blend_fourcc = read_4byte(fp); pLayerData->opacity = read_1byte_BE(fp); uint8_t clipping = read_1byte_BE(fp); pLayerData->flags = read_1byte_BE(fp); uint8_t filler = read_1byte_BE(fp); uint32_t extra_len = read_4byte_BE(fp); bool trans_prot = (pLayerData->flags & 0x1) ? true : false; pLayerData->is_visible = (pLayerData->flags & 0x2) ? false : true; if(extra_len > 0){ uint32_t layer_block_end = ftell(fp) + extra_len; //read mask data uint32_t mask_block_length = read_4byte_BE(fp); switch(mask_block_length){ case 0: pLayerData->is_mask = false; break; case 20: { uint32_t top = read_4byte_BE(fp); uint32_t left = read_4byte_BE(fp); uint32_t bottom = read_4byte_BE(fp); uint32_t right = read_4byte_BE(fp); uint8_t default_color = read_1byte_BE(fp); uint8_t flags = read_1byte_BE(fp); uint16_t padding = read_2byte_BE(fp); pLayerData->is_mask = true; } break; case 36: { uint32_t top = read_4byte_BE(fp); uint32_t left = read_4byte_BE(fp); uint32_t bottom = read_4byte_BE(fp); uint32_t right = read_4byte_BE(fp); uint8_t default_color = read_1byte_BE(fp); uint8_t flags = read_1byte_BE(fp); uint8_t flags2 = read_1byte_BE(fp); uint8_t mask_bg = read_1byte_BE(fp); uint32_t other_top = read_4byte_BE(fp); uint32_t other_left = read_4byte_BE(fp); uint32_t other_bottom = read_4byte_BE(fp); uint32_t other_right = read_4byte_BE(fp); pLayerData->is_mask = true; } break; default: //error return false; break; } //layer blending ranges uint32_t lb_block_length = read_4byte_BE(fp); if(lb_block_length > 0){ if(fseek(fp, lb_block_length, SEEK_CUR)){ return false; } } //read name uint32_t name_read_length; uint8_t name_length = read_1byte_BE(fp); if(name_length == 0){ pLayerData->name = NULL; if(fseek(fp, 4-1, SEEK_CUR)){ return false; } name_read_length = 4; } else{ pLayerData->name = (char*) malloc(name_length+1); if(!fread((pLayerData->name), name_length, 1, fp)){ return false; } int padded_len = name_length + 1; if(fseek(fp, 4-(padded_len%4), SEEK_CUR) < 0){ } pLayerData->name[name_length] = '\0'; name_read_length = name_length + 4 - (padded_len%4); } //set layer type if(pLayerData->flags & 0x10){ if(strcmp(pLayerData->name, "</Layer group>") == 0){ pLayerData->layer_type = PSD_LAYER_TYPE::PSD_CLOSE_GROUP_LAYER; } else{ pLayerData->layer_type = PSD_LAYER_TYPE::PSD_GROUP_LAYER; } } else{ pLayerData->layer_type = PSD_LAYER_TYPE::PSD_NORMAL_LAYER; } //adjastment layer info //sometimes there's a 2-byte padding here, but it's not 4-aligned char sig[4]; long posBefore = ftell(fp); if(!fread(sig, 4, 1, fp)){ return false; } if(memcmp(sig, "8BIM", 4) != 0){ if(fseek(fp, posBefore + 2, SEEK_SET)){ return false; } if(!fread(sig, 4, 1, fp)){ return false; } } if(memcmp(sig, "8BIM", 4) != 0){ if(fseek(fp, posBefore, SEEK_SET)){ return false; } } else{ if(fseek(fp, -4, SEEK_CUR)){ return false; } //read all layer resource while(read_layer_resource(fp)); } long now = ftell(fp); if(layer_block_end != now){ if(fseek(fp, layer_block_end, SEEK_SET)){ return false; } } } return true; }
static const wchar_t *read_string(const unsigned char *loc, const unsigned char *stringtab) { unsigned int n = read_4byte(loc); return n == 0xFFFFFFFF ? NULL : (wchar_t *)(stringtab + n); }