Click here to Skip to main content
15,891,529 members
Please Sign up or sign in to vote.
5.00/5 (2 votes)
See more:
Hi How can I get the start address and size of code segment (.text) build with native cpp? I need this information to build a checksum on code and to detect if my applications code has been modified. It is possible to get a checksum of by opening .exe file and reading it's contents, but taking the checksum from segment .text is much better.

Any systems calls or facilities that would be helpful? Any guidance would be highly appreciated.

Thanks in advance
mr.abzadeh
Posted
Updated 24-Sep-11 20:39pm
v3
Comments
Sergey Alexandrovich Kryukov 25-Sep-11 2:39am    
Interesting problem, my 5 for the question.
--SA
Mehdi Gholam 25-Sep-11 2:46am    
I doubt you can do it, because it might be protected, and any checksum you compute will be off as there is no guarantee the .text on disk and in memory are aligned etc.
mr.abzadeh 25-Sep-11 3:26am    
Protection is not a problem because the code segment has read attribute. It is possible to find the location of a variable in .exe, and even I can store checksum in another place, not in .exe. so aligning is not a problem.
Thanks for your comment
mr.abzadeh

Take a look at GetModuleInformation()[^], it may help.
 
Share this answer
 
Comments
mr.abzadeh 25-Sep-11 4:51am    
Thanks, Fine
It worked well. but it gives total module size, How to get code segment size?
mr.abzadeh
Richard MacCutchan 25-Sep-11 8:16am    
Sorry no idea, I just found a link that may help. You will have to work out the details for yourself by reading the documentation and looking at the other API functions in that section.
mr.abzadeh 25-Sep-11 19:41pm    
Solution 3 works well,
Thank you for your kind notes
mr.abzadeh
One way is to get it like the PE-Loader:
C++
HINSTANCE hInstance = GetModuleHandle(NULL);
PIMAGE_DOS_HEADER pdosheader = (PIMAGE_DOS_HEADER)hInstance;
PIMAGE_NT_HEADERS pntheaders = (PIMAGE_NT_HEADERS)((DWORD)hInstance + pdosheader->e_lfanew);
PIMAGE_SECTION_HEADER psectionheader = (PIMAGE_SECTION_HEADER)(pntheaders + 1);

And loop through the sections to find it, but have in mind to manage the absolute addresses and rebase it.(relocations)
 
Share this answer
 
v2
Comments
mr.abzadeh 25-Sep-11 19:47pm    
Thank you for your reply. This works well and is what I need.
Best reguards
mr.abzadeh
You should create your own segment to store data (like hashes, encrypted values etc). I protect my modules in nearly the same way.
Example:
C++
#pragma once
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <winnt.h>

#ifndef IMAGE_SIZEOF_NT_OPTIONAL_HEADER
#define  IMAGE_SIZEOF_NT_OPTIONAL_HEADER  sizeof(IMAGE_OPTIONAL_HEADER)
#endif // IMAGE_SIZEOF_NT_OPTIONAL_HEADER

#define MYSEGMENT "mydata" // max 8 chars

#pragma data_seg( MYSEGMENT )

struct _MYHASHVALUE
{
  unsigned int  hash;
} MYHASHVALUE = { 42, };

#pragma data_seg()

unsigned int FindSegment(HANDLE hfile,const char* sSegment,unsigned int& cbsize)
{
  IMAGE_DOS_HEADER      img_dos;
  IMAGE_FILE_HEADER      img_file;
  IMAGE_OPTIONAL_HEADER img_optional;
  IMAGE_SECTION_HEADER  img_section;
  long                  more_dos[16];
  long                  nt_sign;
  unsigned long          cb;

  SetFilePointer(hfile,0,0,FILE_BEGIN);
  cb = ReadFile(hfile,&img_dos,sizeof(img_dos),&cb,0)?cb:0;
  if(!cb) return 0;
  if(IMAGE_DOS_SIGNATURE != img_dos.e_magic) return 0;
  ReadFile(hfile,more_dos,sizeof(more_dos),&cb,0);
  SetFilePointer(hfile,img_dos.e_lfanew,0,FILE_BEGIN);

  ReadFile(hfile,&nt_sign,sizeof(nt_sign),&cb,0); //if(IMAGE_NT_SIGNATURE != nt_sign) return 0;
  ReadFile(hfile,&img_file,IMAGE_SIZEOF_FILE_HEADER,&cb,0);

  unsigned int seek_optional = SetFilePointer(hfile,0,0,FILE_CURRENT);
  ReadFile(hfile,&img_optional,IMAGE_SIZEOF_NT_OPTIONAL_HEADER,&cb,0);

  for(unsigned int nofs = 0;nofs<img_file.NumberOfSections;nofs++)
  {
    ReadFile(hfile,&img_section,IMAGE_SIZEOF_SECTION_HEADER,&cb,0);
    if(IMAGE_SIZEOF_SECTION_HEADER>cb) break;
    if(!strcmp((char*)img_section.Name,sSegment))
    {
      cbsize = img_section.SizeOfRawData;
      return img_section.PointerToRawData;
    }
  }
  return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
  if(0<argc)
  {
    HANDLE        hfile = CreateFile(argv[0],GENERIC_READ,0,0,OPEN_EXISTING,0,0);
    unsigned int  cbsize = 0;
    unsigned int  offset = FindSegment(hfile,MYSEGMENT,cbsize);
    
    if((0<offset) && (cbsize>=sizeof(MYHASHVALUE)))
    {
      struct _MYHASHVALUE    myhash;
      unsigned long          rd;
      SetFilePointer(hfile,offset,0,FILE_BEGIN);
      if(ReadFile(hfile,&myhash,sizeof(myhash),&rd,0) && (rd==sizeof(myhash)))
      {
        _tprintf(__T("hash: %i\r\n"),(int)myhash.hash);
      }
    }
    
    CloseHandle(hfile);
  }
  _tprintf(__T("<key> ")); _gettch();
  return 0;
}

Good luck.
 
Share this answer
 
Comments
mr.abzadeh 25-Sep-11 19:46pm    
This is very helpfull for me and i will use this code.
This tecknick is also aplicable in memory, where hInstanse or hModule actually pints to IMAGE_DOS_HEADER.
best regaurds
mr.abzadeh

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900