问题:
Windows XP下CMD下的Set命令不支持用管道符将标准输入赋值到变量:
cmd> echo 321|set env=
cmd> echo %env%
cmd> %env%
只能通过繁杂的for语句来处理(还可能需要对command进行复杂的转义):
for /f %%i in ('command') do set env=%%i
如果只有较少类似语句需要写还可以接受,奈何使用某国外命令行软件需要写大量的批处理脚本,所以...
解决办法:
1.OD反汇编查看cmd.exe,未找到有用的win32 api,只找到了环境变量存储的固定内存区域地址(NO)
2.妄图用OD修改cmd.exe,无奈其汇编繁杂奥妙...(NO)
3.用C调用win32 api来侵入修改父进程内存来达到目的(YES)
源码:
#include <stdio.h>
#include <windows.h>
#include <winbase.h>
#include <tlhelp32.h>
#define READSIZE 0x00001000
#define READADDR 0x00010000
DWORD getPPid();
char* getRet();
int main(int argc,char* argv[])
{
char *c_ret=getRet();
wchar_t w_ret[256];
wchar_t varstr_header[]=L"Zenv=";
wchar_t varstr[2048];
DWORD pid=getPPid();
printf("PID:%d\n",pid);
HANDLE handle;
LPCVOID addr=(LPCVOID)READADDR;
LPVOID buff;
DWORD nSize=READSIZE;
DWORD x=0;
LPDWORD lpd=&x;
lstrcatW(varstr,varstr_header);
swprintf(w_ret, L"%S", c_ret);
lstrcatW(varstr,w_ret);
buff=(LPVOID)malloc(READSIZE);
handle=OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION ,0,pid);
int result=0;
result=ReadProcessMemory(handle,addr,buff,nSize,lpd);
printf("Result:%d\n",result);
DWORD err=GetLastError();
printf("Error Code for call GetLastError:%d\n",err);
printf("Number Of Bytes Read :%d\n",*lpd);
wchar_t line[1024];
int index=0;
int i;
int isWillBreak=0;
LPVOID targetBuff;
LPVOID backupTargetBuff;
backupTargetBuff=targetBuff=(LPVOID)malloc(READSIZE);
memset(targetBuff,0,READSIZE);
for(i=0;i<READSIZE;i++)
{
if(*(short*)buff==0)
{
*(wchar_t*)targetBuff=0;
wprintf(L"%ls\n",line);
index=0;
memset(line,0,1024*2);
if(isWillBreak) break;
isWillBreak=1;
}
else
{
line[index]=*(wchar_t*)buff;
*(wchar_t*)targetBuff=*(wchar_t*)buff;
index++;
isWillBreak=0;
}
buff+=2;
targetBuff+=2;
}
for(i=0;i<(sizeof(varstr)/sizeof(wchar_t));i++)
{
*(wchar_t*)targetBuff=varstr[i];
targetBuff+=2;
}
free(buff);
LPVOID targetAddr=(LPVOID)READADDR;
*lpd=0;
result=WriteProcessMemory(handle,targetAddr,backupTargetBuff,nSize,lpd);
printf("Result:%d\n",result);
err=GetLastError();
printf("Error Code for call GetLastError:%d\n",err);
printf("Number Of Bytes Write :%d\n",*lpd);
}
char* getRet()
{
FILE *fp=stdin;
char *buf_l;
char buf[1024];
int cc;
if(!fp) printf("error stdin");
while(!feof(fp) && (cc=fread(buf,1,sizeof(buf),fp))>0)
{
printf("%s%s","Need set env:",buf);
}
buf_l=buf;
return buf_l;
}
DWORD getPPid()
{
HANDLE hProcessSnap = NULL;
PROCESSENTRY32 pe32 = {0};
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == (HANDLE)-1) return (FALSE);
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hProcessSnap, &pe32))
{
while(pe32.th32ProcessID!=GetCurrentProcessId()) Process32Next(hProcessSnap, &pe32);
}
return(pe32.th32ParentProcessID);
}
编译
:
Windows平台下使用mingw-gcc编译成功,得到Zenv.exe可执行文件
运行:
cmd> echo 321|Zenv
...(显示执行状态)
cmd> echo %Zenv%
321
总结:
1.只支持Windows XP,目测不支持Win7,未尝试对Windows Server各版本测试(本来打算实际运用在具体软件项目中,无奈...原因见下条)
2.国内某0杀毒软件和国外某伞杀毒软件报木马病毒,如国外某伞杀毒软件在软件运行时报木马病毒:TR/Dropper.Gen
3.设置的变量名固定为"Zenv",不过可以据此改写