[文挡]获取PE文件的导出函数列表

王集鹄 2006-06-27 08:24:12
//from
http://ccrun.com/article/go.asp?i=653&d=b2m5o1

uses ImageHlp;

function GetDLLFileExports(
szFileName: PChar;
mStrings: TStrings
): Boolean;
var
hFile: THANDLE;
hFileMapping: THANDLE;
lpFileBase: Pointer;
pImg_DOS_Header: PImageDosHeader;
pImg_NT_Header: PImageNtHeaders;
pImg_Export_Dir: PImageExportDirectory;
ppdwNames: ^PDWORD;
szFunc: PChar;
i: Integer;
begin
Result := False;
if not Assigned(mStrings) then Exit;
hFile := CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, nil,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if(hFile = INVALID_HANDLE_VALUE) then Exit;
hFileMapping := CreateFileMapping(hFile, nil, PAGE_READONLY, 0, 0, nil);
if hFileMapping = 0 then
begin
CloseHandle(hFile);
Exit;
end;

lpFileBase := MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
if lpFileBase = nil then
begin
CloseHandle(hFileMapping);
CloseHandle(hFile);
Exit;
end;

pImg_DOS_Header := PImageDosHeader(lpFileBase);
pImg_NT_Header := PImageNtHeaders(
Integer(pImg_DOS_Header) + Integer(pImg_DOS_Header._lfanew));

if IsBadReadPtr(pImg_NT_Header, SizeOf(IMAGE_NT_HEADERS)) or
(pImg_NT_Header.Signature <> IMAGE_NT_SIGNATURE) then
begin
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
Exit;
end;

pImg_Export_Dir := PImageExportDirectory(
pImg_NT_Header.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].
VirtualAddress);
if not Assigned(pImg_Export_Dir) then
begin
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
Exit;
end;
// 63 63 72 75 6E 2E 63 6F 6D
pImg_Export_Dir := PImageExportDirectory(
ImageRvaToVa(pImg_NT_Header, pImg_DOS_Header, DWORD(pImg_Export_Dir),
PImageSectionHeader(Pointer(nil)^)));

ppdwNames := Pointer(pImg_Export_Dir.AddressOfNames);

ppdwNames := Pointer(ImageRvaToVa(pImg_NT_Header, pImg_DOS_Header,
DWORD(ppdwNames), PImageSectionHeader(Pointer(nil)^)));
if not Assigned(ppdwNames) then
begin
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
Exit;
end;

for i := 0 to pImg_Export_Dir.NumberOfNames - 1 do
begin
szFunc := PChar(ImageRvaToVa(pImg_NT_Header, pImg_DOS_Header,
DWORD(ppdwNames^), PImageSectionHeader(Pointer(nil)^)));
mStrings.Add(szFunc);
Inc(ppdwNames);
end;
UnmapViewOfFile(lpFileBase);
CloseHandle(hFileMapping);
CloseHandle(hFile);
Result := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
GetDLLFileExports('C:\WINDOWS\SYSTEM32\MSSIP32.DLL', Memo1.Lines);
end;
...全文
308 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
zswangII 2006-08-05
  • 打赏
  • 举报
回复
function FindBitmapPoint( //寻找子位图的位置
mBitmapMain: TBitmap; //主位图
mBitmapSub: TBitmap //子位图
): TPoint; //返回子图像存在的坐标,如不存在则返回(-1,-1)
//设计 Zswang 2006-08-04 wjhu111#21cn.com 尊重作者,转贴请注明出处
const
//pfDevice, pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, pf24bit, pf32bit, pfCustom
cBitsPerPixels: array[TPixelFormat] of Byte = (0, 1, 4, 8, 15, 16, 24, 32, 0);
//像素格式所占用的字位数列表
var
I, J, K, L: Integer; //循环变量
vStrMain: string; //主位图一行的像素数据字符串格式
vStrSub: string; //子位图一行的像素数据字符串格式
vLine: PChar; //临时ScanLine用
vBytesSub: Integer; //子位图一行像素数据占用的字节数
vBytesMain: Integer; //主位图一行像素数据占用的字节数
vBitsPerPixels: Byte; //一个像素占用的字位数
vFlag: Boolean;
begin
Result := Point(-1, -1);
///////Begin 安全判断
if not Assigned(mBitmapMain) or not Assigned(mBitmapSub) then Exit;
if mBitmapMain.PixelFormat <> mBitmapSub.PixelFormat then Exit;
if (mBitmapSub.Height <= 0) or (mBitmapSub.Width <= 0) or
(mBitmapMain.Height <= 0) or (mBitmapMain.Width <= 0) then Exit;
///////End 安全判断

vBitsPerPixels := cBitsPerPixels[mBitmapMain.PixelFormat];
if vBitsPerPixels = 0 then Exit;
vBytesSub := (mBitmapSub.Width * vBitsPerPixels + 7) div 8;
vBytesMain := (mBitmapMain.Width * vBitsPerPixels + 7) div 8;
if (vBytesSub = 0) or (vBytesMain = 0) then Exit;
SetLength(vStrSub, vBytesSub);
SetLength(vStrMain, vBytesMain);

vLine := mBitmapSub.ScanLine[0];
Move(vLine^, vStrSub[1], vBytesSub);
for I := 0 to mBitmapMain.Height - 1 do
begin
vLine := mBitmapMain.ScanLine[I];
Move(vLine^, vStrMain[1], vBytesMain);
J := Pos(vStrSub, vStrMain); //寻找子位图第一行是否存在主位图的一行中
L := J;
while J > 0 do
begin
vFlag := True;
for K := 1 to mBitmapSub.Height - 1 do
begin
if I + K >= mBitmapMain.Height then //边界判断
begin
vFlag := False;
Break;
end;
vLine := mBitmapMain.ScanLine[I + K];
Move(vLine^, vStrMain[1], vBytesMain);
vLine := mBitmapSub.ScanLine[K];
Move(vLine^, vStrSub[1], vBytesSub);
if not CompareMem(@vStrSub[1], @vStrMain[J], vBytesSub) then //判断子位图之后的行以相应主位图是否一致
begin
vLine := mBitmapMain.ScanLine[I];
Move(vLine^, vStrMain[1], vBytesMain);
vLine := mBitmapSub.ScanLine[0];
Move(vLine^, vStrSub[1], vBytesSub);
vFlag := False; //不一致打上标记
Break;
end;
end;
if vFlag then //一致则返回
begin
Result := Point((J - 1) div vBitsPerPixels * 8, I);
//计算多少像素位置
Break;
end;
J := Pos(vStrSub, Copy(vStrMain, L + 1, MaxInt)); //考虑子位图第一行在主位图`后面还会出现的情况
if J > 0 then
begin
J := L + J;
L := J;
end;
end;
end;
end; { FindBitmapPoint }

procedure TForm1.Button1Click(Sender: TObject);
var
vPoint: TPoint;
begin
vPoint := FindBitmapPoint(Image1.Picture.Bitmap, Image2.Picture.Bitmap);

///////Begin 测试输出用
Caption := Format('%d,%d', [vPoint.X, vPoint.Y]);
if vPoint.X < 0 then Exit;
Bevel1.Width := Image2.Picture.Bitmap.Width;
Bevel1.Height := Image2.Picture.Bitmap.Height;
Bevel1.Left := Image1.Left + vPoint.X;
Bevel1.Top := Image1.Top + vPoint.Y;
///////End 测试输出用
end;
zswangII 2006-08-05
  • 打赏
  • 举报
回复
//使用如下代码搜索出闲置的方法
uses TypInfo;

procedure UnusedMethods(mComponent: TComponent; mStrings: TStrings);
//设计 Zswang 2006-08-05 wjhu111#21cn.com 尊重作者,转贴请注明出处
type
PMethodInfo = ^TMethodInfo;
TMethodInfo = packed record
rSize: Word;
rAddr: Pointer;
rName: ShortString;
end;

type
TMethodTable = packed record
rCount: Word;
rMethodInfo: array[0..0] of TMethodInfo;
end;
PMethodTable = ^TMethodTable;

var
vEventList: TList;

vMethodTable: PMethodTable;
vMethodInfo: PMethodInfo;
I: Integer;

procedure fScanEvent(mComponent: TComponent);
var
vPropList: PPropList;
vPropCount: Integer;
vMethod: TMethod;
I: Integer;
begin
if not Assigned(mComponent) then Exit;
vPropCount := GetPropList(mComponent, vPropList);
for I := 0 to vPropCount - 1 do
case vPropList[I].PropType^.Kind of
tkMethod:
begin
vMethod := GetMethodProp(mComponent, vPropList[I].Name);
if Assigned(vMethod.Code) then vEventList.Add(vMethod.Code);
end;
end;
for I := 0 to mComponent.ComponentCount - 1 do
fScanEvent(mComponent.Components[I]);
end;
begin
if not Assigned(mStrings) or not Assigned(mComponent) then Exit;
vEventList := TList.Create;
mStrings.BeginUpdate;
try
mStrings.Clear;
vMethodTable := PPointer(PChar(mComponent.ClassType) + vmtMethodTable)^;
vMethodInfo := @vMethodTable^.rMethodInfo[0];
fScanEvent(mComponent);
for I := 0 to vMethodTable.rCount - 1 do
begin
if vEventList.IndexOf(vMethodInfo.rAddr) < 0 then
mStrings.Add(vMethodInfo.rName);
Inc(PChar(vMethodInfo), SizeOf(Word) + SizeOf(Pointer) + SizeOf(Byte) +
Length(vMethodInfo^.rName));
end;
finally
vEventList.Free;
mStrings.EndUpdate;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
UnusedMethods(Self, Memo1.Lines); //输出结果
end;
wudi_1982 2006-07-05
  • 打赏
  • 举报
回复
收藏
  • 打赏
  • 举报
回复
C++ -> delphi
支持:_)
老之 2006-06-27
  • 打赏
  • 举报
回复
支持:)

5,392

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧