1*839529caSEd Maste /*- 2*839529caSEd Maste * Copyright (c) 2015 Kai Wang 3*839529caSEd Maste * All rights reserved. 4*839529caSEd Maste * 5*839529caSEd Maste * Redistribution and use in source and binary forms, with or without 6*839529caSEd Maste * modification, are permitted provided that the following conditions 7*839529caSEd Maste * are met: 8*839529caSEd Maste * 1. Redistributions of source code must retain the above copyright 9*839529caSEd Maste * notice, this list of conditions and the following disclaimer. 10*839529caSEd Maste * 2. Redistributions in binary form must reproduce the above copyright 11*839529caSEd Maste * notice, this list of conditions and the following disclaimer in the 12*839529caSEd Maste * documentation and/or other materials provided with the distribution. 13*839529caSEd Maste * 14*839529caSEd Maste * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*839529caSEd Maste * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*839529caSEd Maste * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*839529caSEd Maste * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*839529caSEd Maste * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*839529caSEd Maste * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*839529caSEd Maste * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*839529caSEd Maste * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*839529caSEd Maste * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*839529caSEd Maste * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*839529caSEd Maste * SUCH DAMAGE. 25*839529caSEd Maste */ 26*839529caSEd Maste 27*839529caSEd Maste #include <errno.h> 28*839529caSEd Maste #include <stdlib.h> 29*839529caSEd Maste #include <string.h> 30*839529caSEd Maste 31*839529caSEd Maste #include "_libpe.h" 32*839529caSEd Maste 33*839529caSEd Maste ELFTC_VCSID("$Id: pe_coff.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); 34*839529caSEd Maste 35*839529caSEd Maste PE_CoffHdr * 36*839529caSEd Maste pe_coff_header(PE *pe) 37*839529caSEd Maste { 38*839529caSEd Maste 39*839529caSEd Maste if (pe->pe_ch == NULL) { 40*839529caSEd Maste errno = ENOENT; 41*839529caSEd Maste return (NULL); 42*839529caSEd Maste } 43*839529caSEd Maste 44*839529caSEd Maste return (pe->pe_ch); 45*839529caSEd Maste } 46*839529caSEd Maste 47*839529caSEd Maste PE_OptHdr * 48*839529caSEd Maste pe_opt_header(PE *pe) 49*839529caSEd Maste { 50*839529caSEd Maste 51*839529caSEd Maste if (pe->pe_oh == NULL) { 52*839529caSEd Maste errno = ENOENT; 53*839529caSEd Maste return (NULL); 54*839529caSEd Maste } 55*839529caSEd Maste 56*839529caSEd Maste return (pe->pe_oh); 57*839529caSEd Maste } 58*839529caSEd Maste 59*839529caSEd Maste PE_DataDir * 60*839529caSEd Maste pe_data_dir(PE *pe) 61*839529caSEd Maste { 62*839529caSEd Maste 63*839529caSEd Maste if (pe->pe_dd == NULL) { 64*839529caSEd Maste errno = ENOENT; 65*839529caSEd Maste return (NULL); 66*839529caSEd Maste } 67*839529caSEd Maste 68*839529caSEd Maste return (pe->pe_dd); 69*839529caSEd Maste } 70*839529caSEd Maste 71*839529caSEd Maste int 72*839529caSEd Maste pe_update_coff_header(PE *pe, PE_CoffHdr *ch) 73*839529caSEd Maste { 74*839529caSEd Maste 75*839529caSEd Maste if (pe == NULL || ch == NULL) { 76*839529caSEd Maste errno = EINVAL; 77*839529caSEd Maste return (-1); 78*839529caSEd Maste } 79*839529caSEd Maste 80*839529caSEd Maste if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { 81*839529caSEd Maste errno = EACCES; 82*839529caSEd Maste return (-1); 83*839529caSEd Maste } 84*839529caSEd Maste 85*839529caSEd Maste if (pe->pe_ch == NULL) { 86*839529caSEd Maste if ((pe->pe_ch = malloc(sizeof(PE_CoffHdr))) == NULL) { 87*839529caSEd Maste errno = ENOMEM; 88*839529caSEd Maste return (-1); 89*839529caSEd Maste } 90*839529caSEd Maste } else { 91*839529caSEd Maste /* Rewrite optional header if `optsize' field changed. */ 92*839529caSEd Maste if (pe->pe_ch->ch_optsize != ch->ch_optsize) 93*839529caSEd Maste pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER; 94*839529caSEd Maste } 95*839529caSEd Maste 96*839529caSEd Maste *pe->pe_ch = *ch; 97*839529caSEd Maste 98*839529caSEd Maste pe->pe_flags |= LIBPE_F_DIRTY_COFF_HEADER; 99*839529caSEd Maste 100*839529caSEd Maste return (0); 101*839529caSEd Maste } 102*839529caSEd Maste 103*839529caSEd Maste int 104*839529caSEd Maste pe_update_opt_header(PE *pe, PE_OptHdr *oh) 105*839529caSEd Maste { 106*839529caSEd Maste 107*839529caSEd Maste if (pe == NULL || oh == NULL) { 108*839529caSEd Maste errno = EINVAL; 109*839529caSEd Maste return (-1); 110*839529caSEd Maste } 111*839529caSEd Maste 112*839529caSEd Maste if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { 113*839529caSEd Maste errno = EACCES; 114*839529caSEd Maste return (-1); 115*839529caSEd Maste } 116*839529caSEd Maste 117*839529caSEd Maste if (pe->pe_oh == NULL) { 118*839529caSEd Maste if ((pe->pe_oh = malloc(sizeof(PE_OptHdr))) == NULL) { 119*839529caSEd Maste errno = ENOMEM; 120*839529caSEd Maste return (-1); 121*839529caSEd Maste } 122*839529caSEd Maste } 123*839529caSEd Maste 124*839529caSEd Maste *pe->pe_oh = *oh; 125*839529caSEd Maste 126*839529caSEd Maste pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER; 127*839529caSEd Maste 128*839529caSEd Maste return (0); 129*839529caSEd Maste } 130*839529caSEd Maste 131*839529caSEd Maste int 132*839529caSEd Maste pe_update_data_dir(PE *pe, PE_DataDir *dd) 133*839529caSEd Maste { 134*839529caSEd Maste 135*839529caSEd Maste if (pe == NULL || dd == NULL) { 136*839529caSEd Maste errno = EINVAL; 137*839529caSEd Maste return (-1); 138*839529caSEd Maste } 139*839529caSEd Maste 140*839529caSEd Maste if (pe->pe_cmd == PE_C_READ || pe->pe_flags & LIBPE_F_FD_DONE) { 141*839529caSEd Maste errno = EACCES; 142*839529caSEd Maste return (-1); 143*839529caSEd Maste } 144*839529caSEd Maste 145*839529caSEd Maste if (pe->pe_dd == NULL) { 146*839529caSEd Maste if ((pe->pe_dd = malloc(sizeof(PE_DataDir))) == NULL) { 147*839529caSEd Maste errno = ENOMEM; 148*839529caSEd Maste return (-1); 149*839529caSEd Maste } 150*839529caSEd Maste } 151*839529caSEd Maste 152*839529caSEd Maste *pe->pe_dd = *dd; 153*839529caSEd Maste 154*839529caSEd Maste pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER; 155*839529caSEd Maste 156*839529caSEd Maste return (0); 157*839529caSEd Maste } 158