编译环境vc6,直接release编译可以得到sys文件
再修改子系统1个字节可以做为题目需求的exe和dll

我只用了一行内联asm,不知道还有没有完全不用内联asm的方法

代码:
#include <windows.h>

#pragma comment (linker, "/subsystem:native")
//#pragma comment (linker, "/subsystem:windows")
#pragma comment (linker, "/entry:real_main")
#pragma comment (linker, "/FIXED:NO")
#pragma comment (linker, "/ALIGN:0x1000")
#pragma comment(linker, "/BASE:0x400000")

typedef DWORD (_cdecl *DBGPRINT)(char *Format,...);
typedef DWORD (WINAPI *OUTPUTDEBUGSTRING)(char *lpOut);

DWORD GetModBase(DWORD x)
{
  DWORD p = x;
  DWORD dwTmp;

  while (p)
  {
    if (*(WORD *)p == 0x5A4D)
    {
      dwTmp = *(DWORD *)(p+0x3C) + p;
      if (*(DWORD *)dwTmp == 0x4550)
      {
        return p;
      }
    }
    p -= 0x10000;
  }

  return 0;
}

PVOID WINAPI GetExportByName(PVOID BaseAddress,char *FuncName)
{
  PIMAGE_NT_HEADERS pNt;
  PIMAGE_EXPORT_DIRECTORY  ExportDir;
  DWORD ExportDirSize;
  PDWORD *ExFunctions;
  PDWORD *ExNames;
  USHORT *ExOrdinals;
  PVOID ExName;
  DWORD Ordinal;
  PVOID Function = NULL;
  int minn,maxn;

  pNt = (PIMAGE_NT_HEADERS)(*(DWORD *)((DWORD)BaseAddress + 0x3C) + (DWORD)BaseAddress);
  if (pNt->OptionalHeader.Magic != 0x10B)
  {
    return NULL;
  }
  ExportDir = (PIMAGE_EXPORT_DIRECTORY)(pNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + (DWORD)BaseAddress);
  ExportDirSize = pNt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
  if (ExportDir == NULL)
  {
    return NULL;
  }
  if (ExportDir->AddressOfNames == 0)
  {
    return NULL;
  }
  
  ExNames = (PDWORD *)((DWORD)BaseAddress + ExportDir->AddressOfNames);
  ExOrdinals = (USHORT *)((DWORD)BaseAddress + ExportDir->AddressOfNameOrdinals);
  ExFunctions = (PDWORD *)((DWORD)BaseAddress + ExportDir->AddressOfFunctions);

  minn = 0;
  maxn = ExportDir->NumberOfNames - 1;
  while (minn <= maxn)
  {
        int mid;
        int res;
    
        mid = (minn + maxn) / 2;
    
        ExName = (PVOID)((DWORD)BaseAddress + (DWORD)ExNames[mid]);
        res = strcmp((PCHAR)ExName, (PCHAR)FuncName);
        if (res == 0)
    {
      Ordinal = ExOrdinals[mid];
      Function = (PVOID)((DWORD)BaseAddress + (DWORD)ExFunctions[Ordinal]);
      if (((DWORD)Function >= (DWORD)ExportDir) &&
        ((DWORD)Function < (DWORD)ExportDir + (DWORD)ExportDirSize))
      {
        return NULL;
      }
      if (Function != NULL)
      {
        return Function;
      }
    }
        else if (minn == maxn)
    {
      break;
    }
        else if (res > 0)
    {
      maxn = mid - 1;
    }
        else
    {
      minn = mid + 1;
    }
  }

  return Function;
}

DWORD WINAPI PeMagic(DWORD s)
{
  DWORD *p;
  DWORD dwTmp;

  p = &s - 1;
  if (p[2] >= 0x80000000)
  {
    //sys
    char szDbgPrint[] = {'D','b','g','P','r','i','n','t',0};
    char szSysInfo[] = {'T','h','i','s',' ','i','s',' ','s','y','s',' ','i','n','f','o',0};
    dwTmp = p[2];
    dwTmp = GetModBase(dwTmp & 0xFFFF0000);
    if (dwTmp)
    {
      DBGPRINT fDbgPrint = (DBGPRINT)GetExportByName((LPVOID)dwTmp,szDbgPrint);
      fDbgPrint(szSysInfo);
    }
  }
  else
  {
    char szOutputDebugStringA[] = {'O','u','t','p','u','t','D','e','b','u','g','S','t','r','i','n','g','A',0};
    char szExeInfo[] = {'T','h','i','s',' ','i','s',' ','e','x','e',' ','i','n','f','o',0};
    char szDllInfo[] = {'T','h','i','s',' ','i','s',' ','d','l','l',' ','i','n','f','o',0};
    dwTmp = *(DWORD *)(s + 0x0C);
    dwTmp = *(DWORD *)(dwTmp + 0x1C);
    dwTmp = *(DWORD *)dwTmp;
    dwTmp = *(DWORD *)(dwTmp + 0x08);
    OUTPUTDEBUGSTRING fOutputDebugString = (OUTPUTDEBUGSTRING)GetExportByName((LPVOID)dwTmp,szOutputDebugStringA);

    if ((p[0] - p[3]) <= 0x2000)
    {
      //dll
      fOutputDebugString(szDllInfo);
    }
    else
    {
      //exe
      fOutputDebugString(szExeInfo);
    }
  }
  
  return 0;
}

static __inline NtCurrentPeb(void)
{
  __asm mov eax,fs:[0x30]
}

DWORD WINAPI real_main(DWORD a,DWORD b)
{
  return PeMagic(NtCurrentPeb());
}
上传的附件 test04.rar