static int pe_save_relocs(void *image, u32 *relocs) { IMAGE_DOS_HEADER *d_head = image; IMAGE_NT_HEADERS *n_head = addof(d_head, d_head->e_lfanew); u32 n_rels = 0; IMAGE_BASE_RELOCATION *reloc; IMAGE_FIXUP_ENTRY *fixup; u32 re_rva, i; if ( (re_rva = n_head->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) == 0 ) { return 1; } for ( reloc = addof(d_head, re_rva); reloc->VirtualAddress != 0; reloc = addof(reloc, reloc->SizeOfBlock) ) { for ( i = 0, fixup = addof(reloc, sizeof(IMAGE_BASE_RELOCATION)); i < (reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / 2; i++, fixup++) { if (fixup->type == IMAGE_REL_BASED_HIGHLOW) { relocs[n_rels++] = reloc->VirtualAddress + fixup->offset; } } } return n_rels; }
static int set_to_val(HKEY h_key, wchar_t *v_name, wchar_t *name) { wchar_t buf[MAX_PATH]; u32 len, cb; wchar_t *p; len = (u32)((wcslen(name) + 1) * sizeof(wchar_t)); cb = sizeof(buf); p = buf; if (RegQueryValueEx(h_key, v_name, NULL, NULL, p8(buf), &cb) != 0) { buf[0] = 0; cb = sizeof(wchar_t); } while (*p != 0) { if (wcscmp(p, name) == 0) { p = NULL; break; } else { p = addof(p, (wcslen(p) * sizeof(wchar_t)) + sizeof(wchar_t)); } } if (p == NULL) { return 1; } memmove(p8(buf) + len, buf, cb); mincpy(buf, name, len); cb += len; return RegSetValueEx(h_key, v_name, 0, REG_MULTI_SZ, p8(buf), cb) == 0; }
void bios_jump_boot(int hdd_n, int n_mount) { if (n_mount != 0) { /* setup backup data block */ mincpy(addof(bdat->bd_base, bdat->bd_size - 384), bdat, offsetof(bd_data, ret_32)); } else { /* clear boot data block signature */ bdat->sign1 = 0; bdat->sign2 = 0; } bdat->boot_dsk = hdd2dos(hdd_n); bdat->rmc.dx = 0x80; bdat->rmc.efl = FL_IF; /* enable interrupts */ bdat->segoff = 0x7C00; bios_jump_rm(); }
static int rmv_from_val(HKEY h_key, wchar_t *v_name, wchar_t *name) { wchar_t buf1[MAX_PATH]; wchar_t *p; u32 cb, len; int succs = 0; do { cb = sizeof(buf1); p = buf1; if (RegQueryValueEx(h_key, v_name, NULL, NULL, p8(buf1), &cb) != 0) { break; } while (*p != 0) { len = (u32)(wcslen(p) * sizeof(wchar_t)); if (wcscmp(p, name) == 0) { memmove(p, p8(p) + len + sizeof(wchar_t), cb - (p - buf1) - len); cb -= len + sizeof(wchar_t); if ( (cb == 0) || (buf1[0] == 0) ) { cb = 0; break; } } else { p = addof(p, len + sizeof(wchar_t)); } } if (cb != 0) { succs = RegSetValueEx(h_key, v_name, 0, REG_MULTI_SZ, p8(buf1), cb) == 0; } else { succs = RegDeleteValue(h_key, v_name) == 0; } } while (0); return succs; }
static NTSTATUS dc_trim_irp(dev_hook *hook, PIRP irp) { PIO_STACK_LOCATION irp_sp = IoGetCurrentIrpStackLocation(irp); PDEVICE_MANAGE_DATA_SET_ATTRIBUTES p_set = irp->AssociatedIrp.SystemBuffer; u32 length = irp_sp->Parameters.DeviceIoControl.InputBufferLength; u64 offset, rnglen; PDEVICE_DATA_SET_RANGE range; PDEVICE_MANAGE_DATA_SET_ATTRIBUTES n_set; u64 off1, off2; u64 len1, len2; u32 i; if ( (length < sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES)) || (p_set->Action != DeviceDsmAction_Trim) || (length < d64(p_set->DataSetRangesOffset) + d64(p_set->DataSetRangesLength)) ) { return dc_forward_irp(hook, irp); } if (dc_conf_flags & CONF_DISABLE_TRIM) { return dc_release_irp(hook, irp, STATUS_SUCCESS); } if ( (n_set = mm_pool_alloc(TRIM_BUFF_MAX(p_set))) == NULL ) { return dc_release_irp(hook, irp, STATUS_INSUFFICIENT_RESOURCES); } n_set->Size = sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES); n_set->Action = DeviceDsmAction_Trim; n_set->Flags = 0; n_set->ParameterBlockOffset = 0; n_set->ParameterBlockLength = 0; n_set->DataSetRangesOffset = _align(sizeof(DEVICE_MANAGE_DATA_SET_ATTRIBUTES), sizeof(DEVICE_DATA_SET_RANGE)); n_set->DataSetRangesLength = 0; if (p_set->Flags & DEVICE_DSM_FLAG_ENTIRE_DATA_SET_RANGE) { if (hook->flags & F_NO_REDIRECT) { TRIM_ADD_RANGE(n_set, hook->head_len, hook->dsk_size - hook->head_len); } else { TRIM_ADD_RANGE(n_set, hook->head_len, LEN_BEFORE_STORAGE(hook)); TRIM_ADD_RANGE(n_set, OFF_END_OF_STORAGE(hook), LEN_AFTER_STORAGE(hook)); } } else { for (i = 0, range = addof(p_set, p_set->DataSetRangesOffset); i < p_set->DataSetRangesLength / sizeof(DEVICE_DATA_SET_RANGE); i++, range++) { if ( (offset = range->StartingOffset) + (rnglen = range->LengthInBytes) > hook->use_size ) { continue; } if (hook->flags & F_NO_REDIRECT) { TRIM_ADD_RANGE(n_set, offset + hook->head_len, min(rnglen, hook->use_size - offset)); continue; } len1 = intersect(&off1, offset, rnglen, hook->head_len, LEN_BEFORE_STORAGE(hook)); len2 = intersect(&off2, offset, rnglen, OFF_END_OF_STORAGE(hook), LEN_AFTER_STORAGE(hook)); TRIM_ADD_RANGE(n_set, off1, len1); TRIM_ADD_RANGE(n_set, off2, len2); } } if (n_set->DataSetRangesLength != 0) { io_hook_ioctl(hook, IOCTL_STORAGE_MANAGE_DATA_SET_ATTRIBUTES, n_set, TRIM_BUFF_LENGTH(n_set), NULL, 0); } mm_pool_free(n_set); return dc_release_irp(hook, irp, STATUS_SUCCESS); }
static int pe2mod(wchar_t *in, wchar_t *out) { IMAGE_DOS_HEADER *d_head; IMAGE_NT_HEADERS *n_head; IMAGE_SECTION_HEADER *t_sect; boot_mod *b_mod = NULL; HMODULE image = NULL; u32 *reloc = NULL; int resl = 1; u32 r_num, offs; HANDLE h_out; u32 i, found; u32 code_off; u32 bytes, n; u8 *s_data; u32 s_size; do { if ( (image = LoadLibraryEx(in, NULL, DONT_RESOLVE_DLL_REFERENCES)) == NULL ) { break; } d_head = pv(dSZ(image) & ~(PAGE_SIZE - 1)); n_head = addof(d_head, d_head->e_lfanew); t_sect = IMAGE_FIRST_SECTION(n_head); found = 0; /* find '.text' section */ for (i = 0; i < n_head->FileHeader.NumberOfSections; i++, t_sect++) { if (_stricmp(t_sect->Name, ".text") == 0) { found = 1; break; } } if (found == 0) { wprintf(L"Invalid PE image %s, section '.text' is not found\n", in); break; } if ( (reloc = calloc(1, n_head->OptionalHeader.SizeOfImage)) == NULL ) { break; } if ( (b_mod = calloc(1, n_head->OptionalHeader.SizeOfImage)) == NULL ) { break; } if (r_num = pe_save_relocs(d_head, reloc)) { /* save needed relocs */ for (i = 0, n = 0; i < r_num; i++) { if (in_reg(reloc[i], t_sect->VirtualAddress, t_sect->Misc.VirtualSize) != 0) { b_mod->relocs[n++] = reloc[i]; } } b_mod->n_rels = n; code_off = _align(sizeof(boot_mod) + n * sizeof(u32), 16); } else { code_off = _align(sizeof(boot_mod), 16); } s_data = addof(d_head, t_sect->VirtualAddress); s_size = t_sect->SizeOfRawData; /* find minimum section RAW size */ for (i = t_sect->SizeOfRawData - 1; i != 0; i--, s_size--) { if (s_data[i] != 0) break; } b_mod->mod_sign = 'DCBM'; b_mod->raw_size = s_size + code_off; b_mod->virt_size = t_sect->Misc.VirtualSize + code_off; b_mod->entry_rva = n_head->OptionalHeader.AddressOfEntryPoint - t_sect->VirtualAddress + code_off; memcpy(addof(b_mod, code_off), s_data, s_size); /* rebase image and fix relocs */ for (i = 0; i < b_mod->n_rels; i++) { offs = b_mod->relocs[i] - t_sect->VirtualAddress + code_off; p32(addof(b_mod, offs))[0] -= n_head->OptionalHeader.ImageBase + t_sect->VirtualAddress - code_off; b_mod->relocs[i] = offs; } h_out = CreateFile( out, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); if (h_out != INVALID_HANDLE_VALUE) { if (WriteFile(h_out, b_mod, b_mod->raw_size, &bytes, NULL) != 0) { wprintf(L"Boot module OK (Virtual size: %d, Raw size: %d, EP: %d)\n", b_mod->virt_size, b_mod->raw_size, b_mod->entry_rva); resl = 0; } CloseHandle(h_out); } else { wprintf(L"Can not write to %s", out); } } while (0); if (reloc != NULL) { free(reloc); } if (b_mod != NULL) { free(b_mod); } if (image != NULL) { FreeLibrary(image); } return resl; }