Link to home
Start Free TrialLog in
Avatar of systan
systanFlag for Philippines

asked on

For CodedK and 8080Diver, but Delphi experts can comment too

Continuetion of the discussion, since I've Awarded and close a previous link.

The last comment of 8080Diver:
8080_Diver:

systan,

Your last request closely resembles the following question (which I defy you to answer Yes or No):

Are you still molesting children?

Are you saying that you are writing the Wininit.dll and you are puttinng a string in the code at the point of the InternetOpenA function?

Or, are you saying that "there exists a WinInit.dll that exports the InternetOpenA function"?

Also, is the 00015912h a relative address or an absolute address?

Finally, are you analyzing this DLL as it resides in memory or as a binary data file that you read and analyze without loading in the usual fashion?

On the other hand, if you know that 00015912h is the address of the InternetOpen entry point, why do you need to search for it ?

Finally, your "code structure" is psuode-Delphi code but could not be written that way.  You would need to find the position of '00015912' within the block of binary data that you have read from the WinInit.dll file but you would need to read blocks with an overlap of  least 8 characters (so that you don't read in 00015 in one block and 912 in the next one.

Given that you are reading WinInit.dll as a data file and that you have the 00015912 as a text string within the file and that you are handling the block reads in an appropriate manner, then yes, that would be one technique for finding the entry point.  Although, that technique cannot be generalized because you cannot guarantee that all DLL's will provide such convenient markers. ;-)
ASKER CERTIFIED SOLUTION
Avatar of CodedK
CodedK
Flag of Greece image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of systan

ASKER

Since I have close and awarded points, and again ask a question after that, this is the last question I ask when was closed.
//---------------------
Ok, a followup question, one last answer please, just YES or NO, no following sentence

if its hard to get the function name inside the application(.exe), what if I assigned or PUT the entry_point or the address of the function that I am searching for:
like this:

Wininet.DLL exports TAble:
...
00015912h            264     InternetOpenA
00013491h            229     InternetConnectA
...

note:
00015912  (the address/entrypoint of InternetOpen in Wininet.DLL) I will put it in my code as string

code structure:
if "00015912" is found at "InternetEXE.exe" then
begin
showmessage('Internet open is found')
end;

iS this a possible technique?
//---------------------

Answered by: 8080Diver on the question body I posted.

Continuetion:

@8080Diver, hi
>Are you still molesting children?
NO, I'm not trying to do anything harm, honestly.

>>and you are puttinng a string in the code at the point of the InternetOpenA function?
YES, not only "InternetOpen"

>Or, are you saying that "there exists a WinInit.dll that exports the InternetOpenA function"?
NO, I'm not looking for a .DLL, I am looking for the Executable Application that has not been launch that contains a function "InternetOpen" or any other functions the application is using.

>Also, is the 00015912h a relative address or an absolute address?
YES, its the relative address
I don't know about absolute address, but if is usable to get the functions used, YES

>Finally, are you analyzing this DLL as it resides in memory or as a binary data file that you read and analyze without loading in the usual fashion?
NO, I'm not analyzing the DLL,
YES, as a binary data file that to be read and analyze without loading in the usual fashion

>On the other hand, if you know that 00015912h is the address of the InternetOpen entry point, why do you need to search for it ?
I'm not really after the "InternetOpen" , I'm only searching it because it is the only function that I was remind to use to search, later on if I know the code, I will search for other functions.
And I just want to let you know that I am not making any BAD application, why do i? instead of BAD, why not making it for a good use later on.
I'm not making a <virus>. why should i, it doesn't point me to the right direction.
As I know many other e-e user's manage to ask question that is very clear that there using it for making a <virus>. I have observed that, and I know you have too.
To be frank again, I'm not using it to build a <virus>.

>Finally, your "code structure" is psuode-Delphi code but could not be written that way.  You would need to find the position of '00015912' within the block of binary data that you have read from the WinInit.dll file but you would need to read blocks with an overlap of  least 8 characters (so that you don't read in 00015 in one block and 912 in the next one.
OK

>Given that you are reading WinInit.dll as a data file and that you have the 00015912 as a text string within the file and that you are handling the block reads in an appropriate manner, then yes, that would be one technique for finding the entry point.  Although, that technique cannot be generalized because you cannot guarantee that all DLL's will provide such convenient markers. ;-)
NO, I'm not reading the DLL as a data file, I'm reading the Executable,  But if is needed to read the DLL because the Executable(.exe) points the function to the DLL, then i will.

Thanks 8080Diver

@CodedK,
I'll post an answer to your questions and ideas, Later, lol, I have to read all the comments, enable for us to communicate well.
Ok, let me finish my dinner. lol
Thank you very much.
Avatar of systan

ASKER

OK, iM back,
@codedK
>is that you want to get the list of the
procedures & functions that an application is using.
NO,
you mean like this:
procedure somepro;
begin
writeln('hello');
end;
function anum:byte;
begin
result:=1;
end;
//So, I read the .exe and determined somepro? anum? NO, not that

But this one:
procedure opennet;
var
  hSession: HINTERNET;
begin
hSession := InternetOpen('MyApp', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
end; //sample only
//////// So, I will determine if Executable is using <"InternetOpen">
That is want I want.

Another sample:
procedure findafile;
var
  searchResult : TSearchRec;   ///////////////// if possible that knowing the Executable is using <"TSearchRec"> also. (if possible also)
begin
  if FindFirst('Unit1.d*', faAnyFile, searchResult) = 0 then
  begin
    repeat
    //sample only
    until FindNext(searchResult) <> 0;
    FindClose(searchResult);
  end;
end;
//////// So, I will determined if Executable is using the function <"FindFrist"> and then the Executable is using also <"FindClose">


OK, I have read your comments
>Another thing you can do is hook every api known and launch an application and check the apis that this application uses and the parameters that the application passes.
But this will only catch API calls.

OK, whats that mean? "will only catch API calls"
If this could make a solution so why not.

>Another thing would be combine my first solution with a Delphi map file.
OK, if is possible, then I should try.

>And if you have the source there is no reason to do that from the beginning.
Oh, I don't know why you said that.

Now, I'm thinking...

Thank you
Systan,
Actually, I never thought you were doing a naughty thing here.  I just thought you might be analyzing a DLL.
In order to be able to search for the text (e.g. "InternetOpen"), you would have to have a something like the following in your code:
procedure opennet;
var
  hSession: HINTERNET;
  DummyString : string;

begin
  DummyString := 'About to call InternetOpen';

 hSession := InternetOpen('MyApp', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
end;

Just putting a comment in the code won't work because comments aren't compiled.  You have to actually have to have the text as part of some line that gets compiled.  You also may lose that line if you compile with the optimization turned on because, uless that variable and the value is used, the optimizer may consider it to be "dead code" and ignore it.
By the way, your answer to my question is below:
>Are you still molesting children?
NO, I'm not trying to do anything harm, honestly.

The implication of  your answer is that you were, at one time, engaging in that activity.  While I seriously doubt that is the case, it illustrates the fact that some questions simply cannot be answered with a "Yes." or "No." . . . they have to have more explanation that either of those two words (or at least the "No." answer) provides.
Similarly, whether or not you can find the calls you are looking for cannot be answered with "Yes." or "No." . . . it has to be a qualified "Maybe." at best.  
>Another thing you can do is hook every api known and launch an application and check the apis that this application uses and the parameters that the application passes.
But this will only catch API calls.

OK, whats that mean? "will only catch API calls"
That means that, because you have hooked/sniffed the API calls, you will be able to catch the calls to the APIs; however, not all calls to DLL functions/procedures are API calls, so you won't ctch those calls.

If this could make a solution so why not.
For the reason stated above.  Unless you have a way to "sniff" or intercept the calls, which can be done with API calls, they won't be apparent to you.  If the DLL is compiled into the application (static rather than dynamic loading of it), then the function/procedure calls are, for all intents and purposes, pretty much like the calls to other functions and procedures in the main part of the application.
>Another thing would be combine my first solution with a Delphi map file.
OK, if is possible, then I should try.


>And if you have the source there is no reason to do that from the beginning.
Oh, I don't know why you said that.


 As he said, unless you have the source code, you won't know what the map refers to; however, if you have the source code (so that you know what the map refers to), why not just look at the source code?
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of systan

ASKER

OK, I understand

Ok, I will ask once more, since this is connected to my questions

I have already the code to List all the functions and RVA by a DLL not running.

Can you give me a Delphi Code Web Link, that shows <To Get All DLL's Used By The Application>?
I've seen it, using Lister(Pluggin) of TotalCommander

Or if you have already the code, I hope you can share it.

And I also found out that the Lister(TCPluggin) could know the functions used by the application, even is compressed by upx.

   wininet.dll
      Import Lookup Table RVA:        00000000h       (Unbound IAT)
      TimeDateStamp:       00000000h  
      ForwarderChain:       00000000h
      DLL Name RVA:       00057FE6h
      Import Address Table RVA:       00056704h
      First thunk RVA:       00056704h
      Ordn        Name
      -----      -----
         0       InternetReadFile
         0       InternetOpenUrlA
         0       InternetOpenA
         0       InternetCloseHandle
         0       HttpQueryInfoA

Thank you
Avatar of systan

ASKER

Ok, please skip my last question about:
<To Get All DLL's Used By The Application>

Now, please help me with this: I have now the code to know what functions the Application is using.
The problem with this, it is not stable, sometimes can get "InternetOpenA" and sometimes not, whats wrong with the code?  
It only gets "InternetOpenA" in the first time of reading the exefile.

here is the code: (please make it stable)
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

const
  IMAGE_DOS_SIGNATURE    = $5A4D;       { MZ }
  IMAGE_OS2_SIGNATURE    = $454E;       { NE }
  IMAGE_OS2_SIGNATURE_LE = $454C;       { LE }
  IMAGE_VXD_SIGNATURE    = $454C;       { LE }
  IMAGE_NT_SIGNATURE     = $00004550;   { PE00 }

  IMAGE_SIZEOF_SHORT_NAME            = 8;
  IMAGE_SIZEOF_SECTION_HEADER        = 40;
  IMAGE_NUMBEROF_DIRECTORY_ENTRIES   = 16;
  IMAGE_RESOURCE_NAME_IS_STRING      = $80000000;
  IMAGE_RESOURCE_DATA_IS_DIRECTORY   = $80000000;
  IMAGE_OFFSET_STRIP_HIGH            = $7FFFFFFF;
  DIRECTORY_ENTRY_EXPORT             = 0;   // Export Directory
  IMAGE_DIRECTORY_ENTRY_IMPORT       = 1;   // Import Directory
  IMAGE_DIRECTORY_ENTRY_RESOURCE     = 2;   // Resource Directory
  IMAGE_DIRECTORY_ENTRY_EXCEPTION    = 3;   // Exception Directory
  IMAGE_DIRECTORY_ENTRY_SECURITY     = 4;   // Security Directory
  IMAGE_DIRECTORY_ENTRY_BASERELOC    = 5;   // Base Relocation Table
  IMAGE_DIRECTORY_ENTRY_DEBUG        = 6;   // Debug Directory
  IMAGE_DIRECTORY_ENTRY_COPYRIGHT    = 7;   // Description String
  IMAGE_DIRECTORY_ENTRY_GLOBALPTR    = 8;   // Machine Value (MIPS GP)
  IMAGE_DIRECTORY_ENTRY_TLS          = 9;   // TLS Directory
  IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG  = 10;   // Load Configuration Directory
  IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = 11;   // Bound Import Directory in headers
  IMAGE_DIRECTORY_ENTRY_IAT          = 12;

type
plist_entry = ^LIST_ENTRY;
LIST_ENTRY = record
  Flink:pLIST_ENTRY;
  Blink:pLIST_ENTRY;
end;

type IMAGE_EXPORT_DIRECTORY= packed record
Characteristics:DWORD;
TimeDateStamp:DWORD;
MajorVersion:WORD;
MinorVersion:WORD;
Name:DWORD;
Base:DWORD;
NumberOfFunctions:DWORD;
NumberOfNames:DWORD;
pAddressOfFunctions:PDWORD;
pAddressOfNames:PDWORD;
pAddressOfNameOrdinals:PWORD;
end;
PIMAGE_EXPORT_DIRECTORY= ^IMAGE_EXPORT_DIRECTORY;

type FPO_DATA =packed record
ulOffStart: DWORD;             // offset 1st byte of function code
cbProcSize:DWORD ;             // # bytes in function
cdwLocals:DWORD;              // # bytes in locals/4
cdwParams:WORD ;              // # bytes in params/4
cbProlog:WORD;           // # bytes in prolog
cbRegs:WORD;           // # regs saved
fHasSEH:WORD;           // TRUE if SEH in func
fUseBP:WORD;           // TRUE if EBP has been allocated
reserved:WORD;           // reserved for future use
cbFrame:WORD;           // frame type
end;
PFPO_DATA=^FPO_DATA;

type
IMAGE_FUNCTION_ENTRY=packed record
  StartingAddress:dword;
  EndingAddress:dword;
  EndOfPrologue:dword;
end;
PIMAGE_FUNCTION_ENTRY=^IMAGE_FUNCTION_ENTRY;

type
  PIMAGE_DOS_HEADER = ^IMAGE_DOS_HEADER;
  IMAGE_DOS_HEADER = packed record      { DOS .EXE header }
    e_magic         : WORD;             { Magic number }
    e_cblp          : WORD;             { Bytes on last page of file }
    e_cp            : WORD;             { Pages in file }
    e_crlc          : WORD;             { Relocations }
    e_cparhdr       : WORD;             { Size of header in paragraphs }
    e_minalloc      : WORD;             { Minimum extra paragraphs needed }
    e_maxalloc      : WORD;             { Maximum extra paragraphs needed }
    e_ss            : WORD;             { Initial (relative) SS value }
    e_sp            : WORD;             { Initial SP value }
    e_csum          : WORD;             { Checksum }
    e_ip            : WORD;             { Initial IP value }
    e_cs            : WORD;             { Initial (relative) CS value }
    e_lfarlc        : WORD;             { File address of relocation table }
    e_ovno          : WORD;             { Overlay number }
    e_res           : packed array [0..3] of WORD; { Reserved words }
    e_oemid         : WORD;             { OEM identifier (for e_oeminfo) }
    e_oeminfo       : WORD;             { OEM information; e_oemid specific }
    e_res2          : packed array [0..9] of WORD; { Reserved words }
    e_lfanew        : Longint;          { File address of new exe header }
  end;

  PIMAGE_FILE_HEADER = ^IMAGE_FILE_HEADER;
  IMAGE_FILE_HEADER = packed record
    Machine              : WORD;
    NumberOfSections     : WORD;
    TimeDateStamp        : DWORD;
    PointerToSymbolTable : DWORD;
    NumberOfSymbols      : DWORD;
    SizeOfOptionalHeader : WORD;
    Characteristics      : WORD;
  end;

  PIMAGE_DATA_DIRECTORY = ^IMAGE_DATA_DIRECTORY;
  IMAGE_DATA_DIRECTORY = packed record
    VirtualAddress  : DWORD;
    Size            : DWORD;
  end;

  PIMAGE_OPTIONAL_HEADER = ^IMAGE_OPTIONAL_HEADER;
  IMAGE_OPTIONAL_HEADER = packed record
   { Standard fields. }
    Magic           : WORD;
    MajorLinkerVersion : Byte;
    MinorLinkerVersion : Byte;
    SizeOfCode      : DWORD;
    SizeOfInitializedData : DWORD;
    SizeOfUninitializedData : DWORD;
    AddressOfEntryPoint : DWORD;
    BaseOfCode      : DWORD;
    BaseOfData      : DWORD;
   { NT additional fields. }
    ImageBase       : DWORD;
    SectionAlignment : DWORD;
    FileAlignment   : DWORD;
    MajorOperatingSystemVersion : WORD;
    MinorOperatingSystemVersion : WORD;
    MajorImageVersion : WORD;
    MinorImageVersion : WORD;
    MajorSubsystemVersion : WORD;
    MinorSubsystemVersion : WORD;
    Reserved1       : DWORD;
    SizeOfImage     : DWORD;
    SizeOfHeaders   : DWORD;
    CheckSum        : DWORD;
    Subsystem       : WORD;
    DllCharacteristics : WORD;
    SizeOfStackReserve : DWORD;
    SizeOfStackCommit : DWORD;
    SizeOfHeapReserve : DWORD;
    SizeOfHeapCommit : DWORD;
    LoaderFlags     : DWORD;
    NumberOfRvaAndSizes : DWORD;
    DataDirectory   : packed array [0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES-1] of IMAGE_DATA_DIRECTORY;
  end;

  PIMAGE_SECTION_HEADER = ^IMAGE_SECTION_HEADER;
  IMAGE_SECTION_HEADER = packed record
    Name            : packed array [0..IMAGE_SIZEOF_SHORT_NAME-1] of Char;
    PhysicalAddress : DWORD; // or VirtualSize (union);
    VirtualAddress  : DWORD;
    SizeOfRawData   : DWORD;
    PointerToRawData : DWORD;
    PointerToRelocations : DWORD;
    PointerToLinenumbers : DWORD;
    NumberOfRelocations : WORD;
    NumberOfLinenumbers : WORD;
    Characteristics : DWORD;
  end;

  PIMAGE_NT_HEADERS = ^IMAGE_NT_HEADERS;
  IMAGE_NT_HEADERS = packed record
    Signature       : DWORD;
    FileHeader      : IMAGE_FILE_HEADER;
    OptionalHeader  : IMAGE_OPTIONAL_HEADER;
  end;

  PIMAGE_RESOURCE_DIRECTORY = ^IMAGE_RESOURCE_DIRECTORY;
  IMAGE_RESOURCE_DIRECTORY = packed record
    Characteristics : DWORD;
    TimeDateStamp   : DWORD;
    MajorVersion    : WORD;
    MinorVersion    : WORD;
    NumberOfNamedEntries : WORD;
    NumberOfIdEntries : WORD;
  end;

  PIMAGE_RESOURCE_DIRECTORY_ENTRY = ^IMAGE_RESOURCE_DIRECTORY_ENTRY;
  IMAGE_RESOURCE_DIRECTORY_ENTRY = packed record
    Name: DWORD;        // Or ID: Word (Union)
    OffsetToData: DWORD;
  end;

  PIMAGE_RESOURCE_DATA_ENTRY = ^IMAGE_RESOURCE_DATA_ENTRY;
  IMAGE_RESOURCE_DATA_ENTRY = packed record
    OffsetToData    : DWORD;
    Size            : DWORD;
    CodePage        : DWORD;
    Reserved        : DWORD;
  end;

  PIMAGE_RESOURCE_DIR_STRING_U = ^IMAGE_RESOURCE_DIR_STRING_U;
  IMAGE_RESOURCE_DIR_STRING_U = packed record
    Length          : WORD;
    NameString      : array [0..0] of WCHAR;
  end;

type LOADED_IMAGE = record
  ModuleName:pchar;
  hFile:thandle;
  MappedAddress:pchar;
  FileHeader:PIMAGE_NT_HEADERS;
  LastRvaSection:PIMAGE_SECTION_HEADER;
  NumberOfSections:integer;
  Sections:PIMAGE_SECTION_HEADER ;
  Characteristics:integer;
  fSystemImage:boolean;
  fDOSImage:boolean;
  Links:LIST_ENTRY;
  SizeOfImage:integer;
end;
PLOADED_IMAGE= ^LOADED_IMAGE;

type IMAGE_LOAD_CONFIG_DIRECTORY = packed record
    Characteristics:DWORD;
    TimeDateStamp:DWORD;
    MajorVersion:WORD;
    MinorVersion:WORD;
    GlobalFlagsClear:DWORD;
    GlobalFlagsSet:DWORD;
    CriticalSectionDefaultTimeout:DWORD;
    DeCommitFreeBlockThreshold:DWORD;
    DeCommitTotalFreeThreshold:DWORD;
    LockPrefixTable:Pointer;
    MaximumAllocationSize:DWORD;
    VirtualMemoryThreshold:DWORD;
    ProcessHeapFlags:DWORD;
    ProcessAffinityMask:DWORD;
    Reserved: array[0..2] of DWORD;
  end;
PIMAGE_LOAD_CONFIG_DIRECTORY=^IMAGE_LOAD_CONFIG_DIRECTORY;

type IMAGE_IMPORT_BY_NAME = packed record
  Hint:WORD;
  Name:DWORD;
end;
PIMAGE_IMPORT_BY_NAME=^IMAGE_IMPORT_BY_NAME;

type IMAGE_THUNK_DATA =packed record
  ForwarderString:PBYTE;
  Func:PDWORD;
  Ordinal:DWORD;
  AddressOfData:PIMAGE_IMPORT_BY_NAME;
end;
PIMAGE_THUNK_DATA=^IMAGE_THUNK_DATA;

type IMAGE_IMPORT_DESCRIPTOR= packed record
  Characteristics:DWORD;
  TimeDateStamp:DWORD;
  ForwarderChain:DWORD;
  Name:DWORD;
  FirstThunk:DWORD;
end;
PIMAGE_IMPORT_DESCRIPTOR = ^IMAGE_IMPORT_DESCRIPTOR;


type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    OpenDialog1: TOpenDialog;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    procedure ProcessFile;
  end;

var
  Form1: TForm1;
  h1,hmap:integer;
  bptr:pointer;
  gptr:pbyte;
  ntsign:plongword;
  doshd:PIMAGE_DOS_HEADER;
  pehd:PIMAGE_FILE_HEADER;
  peoptn:PIMAGE_OPTIONAL_HEADER;
  sectionheads:array of PIMAGE_SECTION_HEADER;
  offsetmem:longword;
  idataphysicaladress:pbyte;
  idata:PIMAGE_IMPORT_DESCRIPTOR;
  modulename,functionname:pchar;
  dptr:plongword;
  ord:word;
  pexpdir:PIMAGE_EXPORT_DIRECTORY;
  pexpnames:pdword;
  expfname:pchar;
implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
memo1.Lines.Clear;
processfile;
end;

procedure TForm1.ProcessFile;
var
i,j:integer;
begin
if opendialog1.Execute=false  then
  exit
else
  h1:=fileopen(opendialog1.FileName,fmShareDenyNone or fmOpenRead);
hmap:=CreateFileMapping(h1,nil,PAGE_READONLY,0,0,nil);
doshd:=PIMAGE_DOS_HEADER(mapviewoffile(hmap,FILE_MAP_READ,0,0,0));
bptr:=doshd;
memo1.Lines.Clear;
memo1.lines.add('DOS Header');
memo1.Lines.Add(' -e_magic='+inttostr(doshd.e_magic));
memo1.Lines.Add(' -e_cblp='+inttostr(doshd.e_cblp));
memo1.Lines.Add(' -e_cp='+inttostr(doshd.e_cp));
memo1.Lines.Add(' -e_crlc='+inttostr(doshd.e_crlc));
memo1.Lines.Add(' -e_cparhdr='+inttostr(doshd.e_cparhdr));
memo1.Lines.Add(' -e_minalloc='+inttostr(doshd.e_minalloc));
memo1.Lines.Add(' -e_maxalloc='+inttostr(doshd.e_maxalloc));
memo1.Lines.Add(' -e_ss='+inttostr(doshd.e_ss));
memo1.Lines.Add(' -e_sp='+inttostr(doshd.e_sp));
memo1.Lines.Add(' -e_csum='+inttostr(doshd.e_csum));
memo1.Lines.Add(' -e_ip='+inttostr(doshd.e_ip));
memo1.Lines.Add(' -e_cs='+inttostr(doshd.e_cs));
memo1.Lines.Add(' -e_lfarlc='+inttostr(doshd.e_lfarlc));
memo1.Lines.Add(' -e_ovno='+inttostr(doshd.e_ovno));
memo1.Lines.Add(' -e_oemid='+inttostr(doshd.e_oemid));
memo1.Lines.Add(' -e_oeminfo='+inttostr(doshd.e_oeminfo));
memo1.Lines.Add(' -e_lfanew='+inttostr(doshd.e_lfanew));
gptr:=bptr;
inc(gptr,doshd.e_lfanew);
ntsign:=plongword(gptr);
if (ntsign^=IMAGE_NT_SIGNATURE) then
  begin
   memo1.Lines.Add('NT Signature<'+inttostr(IMAGE_NT_SIGNATURE)+'>='+inttostr(ntsign^));
   memo1.Lines.Add('Windows Executable');
   memo1.lines.add('------------------------------------------');
   gptr:=bptr;
   inc(gptr,doshd.e_lfanew+4);
   pehd:=PIMAGE_FILE_HEADER(gptr);
   memo1.lines.add('PE Header');
   memo1.Lines.Add(' -Machine='+inttostr(pehd.Machine));
   memo1.Lines.Add(' -Number of Sections='+inttostr(pehd.NumberOfSections));
   memo1.Lines.Add(' -TimeDateStamp='+IntToStr(pehd.TimeDateStamp));
   memo1.Lines.Add(' -PointerToSymbolTable='+IntToStr(pehd.PointerToSymbolTable));
   memo1.Lines.Add(' -Number of Symbols='+IntToStr(pehd.NumberOfSymbols));
   memo1.Lines.Add(' -SizeOfOptionalHeader='+IntToStr(pehd.SizeOfOptionalHeader));
   memo1.Lines.Add(' -Characteristics='+IntToStr(pehd.Characteristics));
   memo1.lines.add('------------------------------------------');
   gptr:=pbyte(pehd);
   inc(gptr,sizeof(IMAGE_FILE_HEADER));
   peoptn:=PIMAGE_OPTIONAL_HEADER(gptr);
   memo1.lines.add('PE Optional Header');
   memo1.Lines.Add(' -Magic='+inttostr(peoptn.Magic));
   memo1.Lines.Add(' -MajorLinkerVersion='+inttostr(peoptn.MajorLinkerVersion));
   memo1.Lines.Add(' -MinorLinkerVersion='+inttostr(peoptn.MinorLinkerVersion));
   memo1.Lines.Add(' -SizeOfCode='+inttostr(peoptn.SizeOfCode));
   memo1.Lines.Add(' -SizeOfInitializedData='+inttostr(peoptn.SizeOfInitializedData));
   memo1.Lines.Add(' -SizeOfUninitializedData='+inttostr(peoptn.SizeOfUninitializedData));
   memo1.Lines.Add(' -AddressOfEntryPoint='+inttostr(peoptn.AddressOfEntryPoint));
   memo1.Lines.Add(' -BaseOfCode='+inttostr(peoptn.BaseOfCode));
   memo1.Lines.Add(' -BaseOfData='+inttostr(peoptn.BaseOfData));
   memo1.Lines.Add(' -ImageBase='+inttostr(peoptn.ImageBase));
   memo1.Lines.Add(' -SectionAlignment='+inttostr(peoptn.SectionAlignment));
   memo1.Lines.Add(' -FileAlignment='+inttostr(peoptn.FileAlignment));
   memo1.Lines.Add(' -MajorOperatingSystemVersion='+inttostr(peoptn.MajorOperatingSystemVersion));
   memo1.Lines.Add(' -MinorOperatingSystemVersion='+inttostr(peoptn.MinorOperatingSystemVersion));
   memo1.Lines.Add(' -MajorImageVersion='+inttostr(peoptn.MajorImageVersion));
   memo1.Lines.Add(' -MinorImageVersion='+inttostr(peoptn.MinorImageVersion));
   memo1.Lines.Add(' -MajorSubsystemVersion='+inttostr(peoptn.MajorSubsystemVersion));
   memo1.Lines.Add(' -MinorSubsystemVersion ='+inttostr(peoptn.MinorSubsystemVersion ));
   memo1.Lines.Add(' -Reserved1 ='+inttostr(peoptn.Reserved1));
   memo1.Lines.Add(' -SizeOfImage ='+inttostr(peoptn.SizeOfImage));
   memo1.Lines.Add(' -SizeOfHeaders ='+inttostr(peoptn.SizeOfHeaders));
   memo1.Lines.Add(' -CheckSum ='+inttostr(peoptn.CheckSum));
   memo1.Lines.Add(' -SubSystem ='+inttostr(peoptn.Subsystem));
   memo1.Lines.Add(' -DllCharacteristics ='+inttostr(peoptn.DllCharacteristics));
   memo1.Lines.Add(' -SizeOfStackReserve ='+inttostr(peoptn.SizeOfStackReserve));
   memo1.Lines.Add(' -SizeOfStackCommit ='+inttostr(peoptn.SizeOfStackCommit));
   memo1.Lines.Add(' -SizeOfHeapReserve ='+inttostr(peoptn.SizeOfHeapReserve));
   memo1.Lines.Add(' -SizeOfHeapCommit ='+inttostr(peoptn.SizeOfHeapCommit));
   memo1.Lines.Add(' -LoaderFlags ='+inttostr(peoptn.LoaderFlags));
   memo1.Lines.Add(' -NumberOfRvaAndSizes ='+inttostr(peoptn.NumberOfRvaAndSizes));
   memo1.lines.add('------------------------------------------');
   setlength(sectionheads,pehd.NumberOfSections);
   for i:=0 to pehd.NumberOfSections -1 do
    begin
     gptr:=pbyte(peoptn);
     inc(gptr,sizeof(IMAGE_OPTIONAL_HEADER)+i*sizeof(IMAGE_SECTION_HEADER));
     sectionheads[i]:=PIMAGE_SECTION_HEADER(gptr);
    end;
   if peoptn.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size=0 then
    begin
     memo1.lines.add('No Export Table Present');
     memo1.lines.add('------------------------------------------');
    end
   else
    begin
     memo1.lines.add('Export Table Present');
     for i:=pehd.NumberOfSections-1 downto 0 do
      begin
       if peoptn.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress>=sectionheads[i].VirtualAddress then
        begin
         offsetmem:=sectionheads[i].PointerToRawData-sectionheads[i].VirtualAddress;
         break;
        end;
      end;
     gptr:=bptr;
     inc(gptr,offsetmem+peoptn.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
     pexpdir:=PIMAGE_EXPORT_DIRECTORY(gptr);
     pexpnames:=pdword(longint(bptr)+integer(PIMAGE_EXPORT_DIRECTORY(gptr).pAddressOfNames));
     for i:=0 to pexpdir.NumberOfNames-1 do
      begin
       expfname:=pchar(integer(bptr)+integer(pexpnames^));
       memo1.lines.add(' -'+expfname);
       inc(pexpnames);
      end;
     memo1.lines.add('------------------------------------------');
    end;
   if peoptn.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size=0 then
    memo1.lines.add('No Import Table Present')
   else
    begin
     memo1.lines.add('Import Table Present');
     for i:=pehd.NumberOfSections-1 downto 0 do
      begin
       if peoptn.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress>=sectionheads[i].VirtualAddress then
        begin
         offsetmem:=sectionheads[i].PointerToRawData-sectionheads[i].VirtualAddress;
         break;
        end;
      end;
     gptr:=bptr;
     inc(gptr,offsetmem+peoptn.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
     idataphysicaladress:=gptr;
     i:=0;
     j:=0;
     while true do
      begin
       gptr:=idataphysicaladress;
       inc(gptr,i*sizeof(IMAGE_IMPORT_DESCRIPTOR));
       idata :=PIMAGE_IMPORT_DESCRIPTOR(gptr);
       if idata.Name = 0 then
        break;
       gptr:=bptr;
       inc(gptr,offsetmem+idata.Name);
       modulename:=pchar(gptr);
       memo1.Lines.Add('Module Name:_____________'+ modulename);
       while true do
        begin
         if (idata.FirstThunk + j*4)= 0 then
          break;
         gptr:=bptr;
         inc(gptr,offsetmem+idata.FirstThunk +j*4);
         dptr:=plongword(gptr);
         gptr:=bptr;
         inc(gptr,offsetmem+dptr^);
         if isbadcodeptr(gptr) then
          break;
         ord:=pword(gptr)^;
         inc(gptr,2);
         functionname:=pchar(gptr);
         if isbadcodeptr(functionname) then
          break;
         if functionname=nil then
          break;
         memo1.Lines.Add('  -Ord:'+inttohex(ord,3)+' Function Name:===='+ functionname);
         inc(j);
        end;
       inc(i);
      end;
    end;
  end;
UnmapViewOfFile(bptr);
closehandle(hmap);
fileclose(h1);
end;

end.


And below is my attach that i test with:
testfiles.zip
Avatar of systan

ASKER

I was supposed to award points directly, I'll try again to accept multiple points.
Avatar of systan

ASKER

Thank you