Advertisement
WilliamWelna

test_pe_iat.c

May 8th, 2017
262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.10 KB | None | 0 0
  1. /*
  2. * Copyright (C) 2016 William H. Welna All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. *     * Redistributions of source code must retain the above copyright
  7. *       notice, this list of conditions and the following disclaimer.
  8. *     * Redistributions in binary form must reproduce the above copyright
  9. *       notice, this list of conditions and the following disclaimer in the
  10. *       documentation and/or other materials provided with the distribution.
  11. *
  12. * THIS SOFTWARE IS PROVIDED BY William H. Welna ''AS IS'' AND ANY
  13. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  14. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  15. * DISCLAIMED. IN NO EVENT SHALL William H. Welna BE LIABLE FOR ANY
  16. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  17. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  18. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  19. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  20. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  21. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  22. */
  23.  
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <windows.h>
  27.  
  28. // For some reason this is always broken so it gets defined here
  29. typedef struct {
  30.     union {
  31.         DWORD Characteristics;
  32.         PIMAGE_THUNK_DATA OriginalFirstThunk;
  33.     };
  34.     DWORD TimeDateStamp;
  35.     DWORD ForwarderChain;
  36.     DWORD Name;
  37.     PIMAGE_THUNK_DATA FirstThunk;
  38. } MY_IMAGE_IMPORT_DESCRIPTOR;
  39.  
  40. int newp() {
  41.     printf("NEWP\n");
  42.     return 0;
  43. }
  44.  
  45. int write_protect_address(void *p, void *d) {
  46.     MEMORY_BASIC_INFORMATION i;
  47.     DWORD t;
  48.     void **p2=(void **)p;
  49.     if(!VirtualQuery(p, &i, sizeof(MEMORY_BASIC_INFORMATION)))
  50.         return -1;
  51.     if(!VirtualProtect(i.BaseAddress, i.RegionSize, PAGE_EXECUTE_READWRITE, &i.Protect))
  52.         return -2;
  53.     p2[0]=d; // This void** recast is to make gcc/mingw happy
  54.     if(!VirtualProtect(i.BaseAddress, i.RegionSize, i.Protect, &t))
  55.         return -3;
  56.     return 0;
  57. }
  58.  
  59. int mylen(char *s) {
  60.     int c=0;
  61.     char *p;
  62.     for(p=s; *p != '\0'; *p++)
  63.         c++;
  64.     return c;
  65. }
  66.  
  67. int mycmp(char *s1, char *s2, int size) {
  68.     int x;
  69.     for(x=0; x < size; x++)
  70.         if(s1[x] != s2[x])
  71.             return 0;
  72.     return 1;
  73. }
  74.  
  75. int mysafecmp(char *s1, char *s2) {
  76.     int s1_size = mylen(s1), s2_size = mylen(s2);
  77.     if(s1_size > s2_size)
  78.         return mycmp(s1, s2, s2_size);
  79.     else
  80.         return mycmp(s1, s2, s1_size);
  81. }
  82.  
  83. char *upper(char *s) {
  84.     char *p;
  85.     for(p=s; *p!=0; *p++) {
  86.         if((*p > 96) && (*p < 123)) {
  87.             *p=*p-32;
  88.         }
  89.     }
  90.     return s;
  91. }
  92.  
  93. void *self_iat_patch(char *fname, void *new_address) {
  94.     void *base = (void *)0x400000;
  95.     void *old_address=NULL;
  96.     IMAGE_FILE_HEADER *image_header;
  97.     IMAGE_OPTIONAL_HEADER *optional_header;
  98.     MY_IMAGE_IMPORT_DESCRIPTOR *ip, *Imports;
  99.     unsigned int *el = (unsigned int *)0x40003c;
  100.     int x, ret;
  101.    
  102.     x=*(el);
  103.     image_header = x+base+4;
  104.     optional_header = (void *)image_header+sizeof(IMAGE_FILE_HEADER);
  105.     Imports=(MY_IMAGE_IMPORT_DESCRIPTOR *)(((char *)base)+optional_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
  106.  
  107.     for(ip=Imports; ip->Name!=0; ip++) {
  108.         PIMAGE_IMPORT_BY_NAME thunkData;
  109.         DWORD *thunk, thunkref;
  110.         FARPROC *addrs;
  111.         thunkref=(DWORD)ip->FirstThunk; addrs=(FARPROC *)(((void *)base)+thunkref);
  112.         thunkref=(DWORD)ip->OriginalFirstThunk; thunk=(DWORD *)(((char *)base)+thunkref);
  113.         for(x=0; thunk[x]!=0; ++x) {
  114.             if(!IMAGE_SNAP_BY_ORDINAL(thunk[x])) {
  115.                 thunkData=(PIMAGE_IMPORT_BY_NAME)(((char *)base)+thunk[x]);
  116.                 if(mysafecmp(fname, thunkData->Name)) {
  117.                     old_address=addrs[x];
  118.                     if(!write_protect_address(&addrs[x], new_address))
  119.                         printf("Patched %p to %p -> %s\n", old_address, addrs[x], thunkData->Name);
  120.                 }
  121.             }
  122.         }
  123.     }
  124.     return old_address;
  125. }
  126.  
  127. int main(int argc, char **argv) {
  128.     self_iat_patch("fprintf", &newp);
  129.     fprintf(stdout, "test");
  130.     fprintf(stdout, "test");
  131.     fprintf(stdout, "test");
  132.     fprintf(stdout, "test");
  133. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement