正在加载...
 
  • 共17文章
  • 1
  • 2
  • 3
  • >
用用delphi也不错  

   delphi原来也可以嵌套汇编代码,很好,很强大,就是pascal的代码风格很受不了,找了本delphi开发人员手册,一下才发现,我靠96M,要人命啊。

   VB用call原来很麻烦,看来要主攻delphi了,强大的OOP,方便的code injection。吼吼,很适合最近无聊有TMD忙死的我用。周五,小搞了一晚上,ce的入门题目,自己独立完成了,很happy,试着找了几个游戏的base,很失败,看来用的还不熟练。据说,现在用call也不是很好了,检测的很严格,于是装上了antihook来对抗检测,TMD,冲突好严重。要是自己够牛B,偶就直接搞协议型的了。没办法,谁让自己分析能力垃圾,编程能力垃圾捏。 

  希望不久能用自己的程序打游戏,不过想想要掌握的东西:破解,调试。我就头疼,有可能又是遥远的未来才能实现的梦想。MD反正是闲着,慢慢玩了。

  最近发现菜比zeta没动静了,难道让女流氓XXXX了?凌御还在JJYY,至少每天有点看的东西。K4Y的BLOG也是常年不更新,丫的估计很忙。npicc到处灌水,JJYY太少,希望继续努力,发点八卦的东西。

  如果你不知道我前面说的是什么,很抱歉,最近我在和谐着。说清楚了不和谐。可以来这里看看http://forum.cheatengine.org/index.php

 

  

 

 

 

   

 

 

 

 

 

 

标签:让人发疯的 | 浏览数(411) | 评论数(6) | 2007-10-13
郁闷 给饿醒了  

  MD用大瓶可乐充饥,水分和CO2都排泄出来了,精力充沛的偶刚睡2个小时就饿醒了,郁闷

标签:让人发疯的 | 浏览数(503) | 评论数(2) | 2007-09-01
一篇关于流动性过剩的文章,个人觉得挺透彻的  

【什么是流动性】

我们谈到的流动性(Liquidity )有三种用法或涵义,一是指整个宏观经济的流动性,指在经济体系中货币的投放量的多少,现在所谓流动性过剩就是指有过多的货币投放量,这些多余的资金需要 寻找投资出路,于是就有了投资/经济过热现象,以及通货膨胀危险。造成目前流动性过剩的根源来自于中国不断推升的贸易顺差,出口企业不断把收回的美元兑换 给国家,国家就得不断向经济体系投放人民币,这就造成了流动性过剩的现象。

在股票市场,我们提到流动性就整个市场而言指参与交易资金 相对于股票供给的多少,这里的资金包括场内资金,既己购买了股票的资金,也就是总流通市值,以及场外资金,就是还在股票帐户里准备随时入场的资金。如果在 股票供给不变的情况下,或交易资金增长速度快于股票供给增长速度的话,即便公司盈利不变,也会导致股价上涨,反之亦然,这是很简单的需求供给关系,但这种 股价上涨是有限度的,受过多或叫过剩的资金追捧导致股价过度上涨而没有业绩支撑,终难持久,这种资金就是我们常说的热钱。

上面两种流动性多数情况下会有关联,既经济出现流动性过剩通常会引发股票市场的流动性过剩,所以当国家开始收紧银根时,股票市场就会失去资金供给,表现不佳。

针 对于个股,流动性是另一个概念,指股票买卖活动的难易,也就是说我买了这支股票后是否容易卖出,我们常说这支股票流动性很差,就是指很难按理想价格卖出, 所以流动性差的股票多是小盘股或高度控盘的股票,是不适合大资金运作的,即便买完之后股价涨上去了,但卖不掉,对于大资金风险更大,所以他们更愿意在流动 性很好的大盘股里运作,那里交投活跃,大量买卖也不会引起股价明显变动。不过中小投资者就自由很多了,由于资金量少,可以有很多选择。

【什么是流动性过剩】

    当前,流动性过剩(Excess Liquidity)已经成为中国经济乃至全球经济的一个重要特征。

    实际上,流动性过剩这个词并不准确。过剩是个量的概念,而流动性过剩却在表达一种状态。笔者倾向于认为这种状态用“流动性过高”表达比较合适。

     所谓“流动性”,实际上是指一种商品对其他商品实现交易的难易程度。衡量难易程度的标准是该商品与其他商品实现交易的速度。当该商品与其他商品交易速度加 快,也就是非常容易实现交易的时候,流动性就会出现过剩;当该商品与其他商品的交易出现速度减缓,也就是实现交易非常困难的时候,流动性就会出现不足。

    在一般的宏观经济分析中,流动性过剩被用来特指一种货币现象。也就是说,在现实的经济分析中,上面定义当中的基准商品仅仅被当作货币,因为货币本质上也是一种商品。欧洲中央银行(ECB)的就把流动性过剩定义为实际货币存量对预期均衡水平的偏离。

     对通胀的定义也有多种,但通胀的基本特征包括两个方面:第一,流通中的货币出现膨胀状态,即货币贬值。第二,一般商品和劳务的价格普遍地、持续地上涨。注 意普遍和持续这两个概念有助于把通货膨胀和其他的物价上涨现象区分开来。Inflation除了通货膨胀的意思之外,还有信用膨胀、物价暴涨的含义,从这 些字意上我们也可以了解到,货币过多和信用膨胀,物价持续普遍上涨是三位一体,不可分割的。

    那么,流动性过剩与通货膨胀是什 么关系呢?我们知道,预期货币存量均衡水平实际对应着合意的物价水平。当我们说流动性过剩,即货币超发时,预期均衡的货币存量没有变化,此时,物价没有出 现普遍、持续的上涨。但是,由于实际货币存量已经超过合意水平,物价水平有可能普遍上涨,从而出现通货膨胀。这中间存在一定的时滞。 如果中央银行此时能够控制货币发行并使实际货币存量回归到预期的均衡水平,那么物价水平普遍、持续上涨就有可能不会发生。反之,物价水平就可能出现普遍、 持续上涨。

    这里,又不得不涉及货币的本质、货币如何超发以及从货币超发到物价普遍上涨之间的传递机制问题。在马歇尔那里, “货币”一词有较大的伸缩性,如果没有相反的意义,“货币”可以看成是“通货”的同义语。在金融市场上,“货币的价值”在任何时候都等于贴现率或短期贷款 所收的利率。在托马斯·梅耶那里,足值的商品货币指的是作为商品的价值和作为交换中介的价值完全相等的货币。如果货币作为商品自身的价值不能与它作为货币 的价值完全相等,且不能用以(直接)兑换商品,就称为信用货币。

    笔者认为,货币实质上是中央银行代替社会发行的一部分人对另 一部分人的负债。信用货币表明了一种债权债务关系,而流通纸币则实际上是一种特殊形式的债券。当存在流动性过剩时,货币与其他商品实现交易的速度大大加快 了。这表明,持有货币的债权人希望尽快把货币与其他商品交换,实现自己的债权。由于所有的债权人都希望用货币换回其他商品,货币就出现了贬值的压力。货币 流通速度越快,则货币贬值压力越大。这时,如果货币持有人手中的债券无法得到等值的偿还,就会发生抢购风潮,物价飞涨,整个社会就会发生通货膨胀。

    中国虽然在上世纪90年代中期发生过严重的通货膨胀,但是,近几年M2GDP继续维持高位,却没有发生通货膨胀,一般认为有以下几个原因:

     第一,从货币超发压力到全社会物价水平的普遍、持续上涨有一定的时滞。由于现代信用货币的复杂性,货币超发压力往往不会立即导致物价的广泛上涨。这种滞后 期的长短往往取决于宏观经济数据的准确程度、不同价格指数的重视程度、社会公众和企业对宏观经济的预期以及国家货币和财政部门对于通胀的态度。我们看到, 现实经济中货币发行量尽管已经在高位运行数年,而消费物价指数可能仍然是负数;而当货币当局为了抑制通胀将各个口径的货币发行降下来时,消费物价指数可能 仍然在上涨。如此,物价上涨相对于货币超发压力的滞后效应,仍然会造成反通胀理论和政策上的混乱。例如,一些观点认为,我国货币多发根本不会带来物价上涨 压力,应当以货币超发来抑制有效消费需求不足导致的价格下降。这样的论点把时滞效应理解成了货币多发与物价上涨没有必然联系。“通货”的“膨胀”,并不会 立刻带来“通货膨胀”,但时间上的不一致并不能否认货币超发是全社会物价水平的普遍、持续上涨的最基本的成因。

    第二,收入差距扩大。财富向少数人集中,而富人的边际消费倾向比较低。居民把大量的收入存入银行作为养老金、医疗费用以及子女的教育费用。

    第三,消费品企业的激烈竞争,阻断了商品价格水平从原材料到工业消费品价格的传递,从不动产和资产价格到普通居民消费品价格的传递。

     但是,我们也要明确,资产价格膨胀也会导致通货膨胀。刚卸任国家货币政策委员会委员的余永定先生就指出,仅看到物价指数的稳定而不注意金融资产和不动产价 格的上涨, 很可能会导致货币政策过松, 以致不能及时制止泡沫经济。他举了日本的例子,上世纪80 年代末, 日本股票价格和不动产价格急剧上升, 但物价指数却相当平稳, 因而没有提高利息率, 紧缩银根。泡沫破裂后, 日本陷入战后最严重的经济危机。余先生还提醒说,在目前中国存在大量超发、但暂时沉积为居民储蓄存款的货币(我们暂时将这一部分货币称之为“沉积货币”) 的情况下, 资本市场的过度发展(也可以是房地产市场的过度发展)很可能激活处于冬眠状态的沉积货币,暂时退出流通的货币将重返流通领域去追逐商品, 从而导致通货膨胀的复活。

    所以,流动性过剩是通货膨胀的前兆,从流动性过剩到通货膨胀只有一步之遥。

【流动性过剩问题的解决】

可以从三方面解决流动性过剩问题。

·首先,改变信贷投向结构,大力开发中小企业和个人信贷市场。通过营造良好的金融生态环境,规范金融生态秩序,强化全社会信用体系建设,建立以保护债权为中心的规范有序的社会法律和信用环境,消化中国持续增长的国民储蓄。

·其次,大力发展资本市场,调整金融市场结构。鼓励合规资金进入股票等资本市场,鼓励和扩大企业通过发债方式筹措资金,培养机构投资者,使之成为资本市场的主导力量。建立统一的全国债券市场、多元化的市场风险配置机制,有效配置金融资源。

· 最后,鼓励、支持银行业的产品创新,调整金融产品结构,疏导流动性。要拓展商业银行的运作空间;发展货币市场基金,发展包括资产证券化,以债券为基础的衍 生工具以及多种组合的利率、汇率产品和债券品种系列等新产品,发展公司和私人理财增值服务。发展商业银行资产负债表外的理财托管产品,逐渐改变商业银行的 生存方式。

标签:让人发疯的 | 浏览数(825) | 评论数(0) | 2007-07-26
一个epo的扫描器  

  从4月1日到现在一直再看epo,郁闷的是天天最少7节课,一个代码往往要看好几天。结果很难抓住重点,头大的说~
  google了一下找了个epo的扫描器,希望对看管们有点帮助


  /*

EPOS - Heuristic Entry-point Obscuring (Virus) Scanner
and Win32. CTX.Phage disinfector

by Piotr Bania <bania.piotr@gmail.com>
http://www.piotrbania.com



*/


#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>



#define O_CALL 0xE8
#define O_JMP 0xE9


#define TEMP_FILE_NAME "C:\_$temp.vir"


void scan_file(char *name);
bool try_disinfect(char *name, DWORD where_ctx, DWORD caller, DWORD upa, DWORD sv);




int main(int argc, char *argv[]) {

printf("---------------------------------------------------------------------------\n");
printf(" EPO-SCANNER - (c) Piotr Bania\n");
printf(" http://pb.specialised.info\n");
printf("---------------------------------------------------------------------------\n");

if (argc<2)
{
printf("[!] Usage: EPO-s.exe <file>\n");
printf("[!] Press any key to exit.\n");
getch();
return 0;
}

printf("[+] Trying to scan: %s\n",argv[1]);
scan_file(argv[1]);

return 0;
}


void scan_file(char *name) {
HANDLE file,map;
void* mymap;
DWORD startrange = NULL, endrange = NULL, i = NULL, loc = NULL, temp_loc = NULL, upa = NULL;
DWORD where_ctx = NULL,caller = NULL, sv = NULL;
PIMAGE_DOS_HEADER pMZ = NULL;
PIMAGE_NT_HEADERS pPE = NULL;
PIMAGE_SECTION_HEADER pSH = NULL,pSHC = NULL;
char *temp_name = TEMP_FILE_NAME;
WORD sections;
int count=0;


if (!CopyFile(name,temp_name,FALSE))
{
printf("[-] Error: copying file failed - no future disinfection possible, error: %d\n",GetLastError());
}


if ((file = CreateFile(name,GENERIC_READ | FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL)) == INVALID_HANDLE_VALUE)
{
printf("[-] Error: Cannot open file - error: %d\n",GetLastError());
goto error_mode1;
}

if ((map = CreateFileMapping(file,NULL,PAGE_READWRITE | SEC_COMMIT,NULL,NULL,NULL)) == NULL)
{
printf("[-] Error: Cannot create map of file - error: %d\n",GetLastError());
goto error_mode2;
}

if ((mymap = MapViewOfFile(map,FILE_MAP_ALL_ACCESS,NULL,NULL,NULL)) == NULL)
{
printf("[-] Error: Cannot create map view of file - error: %d\n",GetLastError());
goto error_mode3;
}

pMZ=(PIMAGE_DOS_HEADER) mymap;

if (pMZ->e_magic != IMAGE_DOS_SIGNATURE)
{
printf("[-] Error: Bad MZ signature\n");
goto error_mode4;
}

pPE=(PIMAGE_NT_HEADERS) ((DWORD)mymap + pMZ->e_lfanew);

if (IsBadReadPtr((VOID*)pPE,sizeof(PIMAGE_NT_HEADERS)) == TRUE)
{
printf("[-] Error: Bad PE file\n");
goto error_mode4;
}

if (pPE->Signature != IMAGE_NT_SIGNATURE || pPE->FileHeader.NumberOfSections == NULL)
{
printf("[-] Error: Bad PE file\n");
goto error_mode4;
}

if (pPE->OptionalHeader.ImageBase <= 0 || pPE->OptionalHeader.AddressOfEntryPoint <= 0 || pPE->FileHeader.NumberOfSections <= 0)
{
printf("[-] Error: Bad PE file\n");
goto error_mode4;
}

printf("[+] Imagebase: 0x%.08x - Entrypoint: 0x%.08x (0x%.08x)\n",pPE->OptionalHeader.ImageBase,pPE->OptionalHeader.AddressOfEntryPoint,pPE->OptionalHeader.ImageBase+pPE->OptionalHeader.AddressOfEntryPoint);

sections = pPE->FileHeader.NumberOfSections;
pSH = (PIMAGE_SECTION_HEADER)((DWORD)mymap+pMZ->e_lfanew + sizeof(IMAGE_NT_HEADERS));


while (sections != 0)
{
if (IsBadReadPtr(&pSH,sizeof(PIMAGE_SECTION_HEADER)) == TRUE)
{
printf("[-] Error: Bad PE file\n");
goto error_mode4;
}

char *secname=(char *) pSH->Name;
if (secname == NULL) strcpy(secname,"NONAME");

startrange=(DWORD) pSH->VirtualAddress + pPE->OptionalHeader.ImageBase;
endrange=(DWORD) startrange + pSH->Misc.VirtualSize;

if (startrange <=0 || startrange <= pPE->OptionalHeader.ImageBase || endrange <=0 || pPE->OptionalHeader.ImageBase <= 0 || pSH->Misc.PhysicalAddress < 0 || pSH->SizeOfRawData < 0)
{
printf("[-] Error: The %s section is broken\n",secname);
goto error_mode4;
}

if (pSH->VirtualAddress <= pPE->OptionalHeader.AddressOfEntryPoint && pPE->OptionalHeader.AddressOfEntryPoint < pSH->VirtualAddress + pSH->Misc.VirtualSize)
{
printf("[+] Checking call/jump requests from %s section (EP)\n",secname);
pSHC = pSH;
}


pSH++;
sections--;
}

pSH--;

if (pSHC == NULL)
{
printf("[-] Error: invalid entrypoint\n");
goto error_mode4;
}


printf("[+] Starting heuristics scan on %s section...\n\n",pSHC->Name);

if (pSHC == pSH)
{
printf("[!] Alert: Entrypoint points to last section (%s) -> 0x%.08x\n",pSH->Name,pPE->OptionalHeader.AddressOfEntryPoint + pPE->OptionalHeader.ImageBase);
printf("[!] Alert: The file may be infected!\n");
printf("[+] No deep-scan action was performed\n");
goto error_mode4;
}


printf("[+] Starting from offset: 0x%.08x\n",pPE->OptionalHeader.ImageBase + pSHC->VirtualAddress);

for (i = 0; (i != pSHC->SizeOfRawData); i++)
{
loc = (DWORD)((DWORD)mymap + pSHC->PointerToRawData) + i;

if ((*(BYTE*)loc) == O_CALL || (*(BYTE*)loc) == O_JMP )
{
loc++;
temp_loc = (DWORD)((DWORD)pSHC->VirtualAddress + i + (*(DWORD*)loc)) + 5;

if (temp_loc >= pSH->VirtualAddress && temp_loc <= pSH->VirtualAddress + pSH->Misc.VirtualSize)
{
printf("[!] Alert: Detected request to %s(0x%.08x) section at: 0x%.08x\n",pSH->Name,pPE->OptionalHeader.ImageBase + temp_loc, pSHC->VirtualAddress + pPE->OptionalHeader.ImageBase + i);
if (where_ctx == NULL)
{
where_ctx = (DWORD)(pPE->OptionalHeader.ImageBase + temp_loc);
caller = (DWORD)(pSHC->VirtualAddress + pPE->OptionalHeader.ImageBase + i);
upa = (DWORD)(pSH->VirtualAddress + pPE->OptionalHeader.ImageBase);
sv = loc - 1;

}
count++;
}
loc--;
}

}

printf("[+] Scan finished, %d suspected instruction(s) found.\n",count);
if (count != 0)
{
printf("[!] Warning: the file may be infected!\n");
printf("\n[?] Do you want to try dis-infect the file?\n");
printf("[?] Warning: the file may be executed if this is not the CTX.Phage\n");
printf(" infection.\n");
printf("[?] Disinfect: (y)es / (n)o ? \n");

if (getch() == 'y') try_disinfect(name, where_ctx, caller, upa, sv);


}

error_mode4:
UnmapViewOfFile(mymap);

error_mode3:
CloseHandle(map);

error_mode2:
CloseHandle(file);

error_mode1:
DeleteFile(temp_name);

}


bool try_disinfect(char *name, DWORD where_ctx, DWORD caller, DWORD upa, DWORD sv) {
STARTUPINFO si;
PROCESS_INFORMATION pi;
CONTEXT tc;
DEBUG_EVENT de;
DWORD stack_v = NULL, _GetProcAddress = NULL, oldp;
unsigned char patch[4] = { 0x90, 0x90, 0xCC };
unsigned char ctx_sig[15] = { 0x6A, 0x00, 0x6A, 0x05, 0xE8, 0x05, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90, 0x90, 0x90, 0x50 };
unsigned char ctx_fly[15];
char *temp_name = TEMP_FILE_NAME;
int fe=NULL, found=NULL;


_GetProcAddress = (DWORD) GetProcAddress(LoadLibrary("KERNEL32.DLL"), "GetProcAddress");


GetStartupInfo(&si);
if (!CreateProcess(NULL,temp_name,NULL,NULL,FALSE,DEBUG_PROCESS + DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si, &pi))
{
printf("[-] Error: cannot create process, error: %d\n",GetLastError());
goto error_di;
}

printf("\n[+] Process created, pid=0x%.08x\n",pi.dwProcessId);
printf("[+] Starting emulation engine...\n");


while (1)
{
WaitForDebugEvent(&de,INFINITE);
if (de.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) {
printf("[!] Error: ups process exited...\n");
goto error_term;
}

if (de.dwDebugEventCode == EXCEPTION_DEBUG_EVENT)
{
if (de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
if (de.u.Exception.dwFirstChance == TRUE)
{
printf("[+] Exception occured at: 0x%.08x, passing to program.\n",de.u.Exception.ExceptionRecord.ExceptionAddress);
ContinueDebugEvent(de.dwProcessId,de.dwThreadId,DBG_EXCEPTION_NOT_HANDLED);
}
else
{
printf("[-] Hard error occured, terminating the program\n");
printf("[-] Disinfecting failed\n");
goto error_term;
}

}





if (de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT)
{
if (fe == NULL)
{
fe = 1;
printf("[+] Reached break point at 0x%.08x\n",de.u.Exception.ExceptionRecord.ExceptionAddress);
printf("[+] Modifing 4 bytes at host stack\n");


tc.ContextFlags = CONTEXT_CONTROL;
if (!GetThreadContext(pi.hThread, &tc))
{
printf("[-] Failed to get thread context, error: %d\n",GetLastError());
printf("[-] Disinfecting failed\n");
goto error_term;
}

ReadProcessMemory(pi.hProcess, (void*)tc.Esp, &stack_v,4,NULL);

if (stack_v == NULL)
{
printf("[-] Error: reading from stack failed\n");
printf("[-] Disinfecting failed\n");
goto error_term;
}

tc.Esp = tc.Esp - 4;
caller += 5;

if (!WriteProcessMemory(pi.hProcess, (void*)tc.Esp, &caller, 4, NULL))
{
printf("[-] Error: writing to stack failed\n");
printf("[-] Disinfecting failed\n");
goto error_term;
}
printf("[+] Stack modified, 0x%.08x added caller -> 0x%.08x\n",tc.Esp, caller);

printf("[+] Redirecting EIP to 0x%.08x...\n",where_ctx);
tc.Eip = where_ctx;

if (!SetThreadContext(pi.hThread, &tc))
{
printf("[-] Failed to set thread context, error: %d\n",GetLastError());
printf("[-] Disinfecting failed\n");
goto error_term;

}

VirtualProtectEx(pi.hProcess, (void*) _GetProcAddress, sizeof(patch), PAGE_READWRITE, &oldp);
WriteProcessMemory(pi.hProcess, (void*) _GetProcAddress, &patch, sizeof(patch), NULL);
VirtualProtectEx(pi.hProcess, (void*) _GetProcAddress, sizeof(patch), oldp, &oldp);

printf("[+] Placed breaker at 0x%.08x\n",_GetProcAddress);

ContinueDebugEvent(de.dwProcessId,de.dwThreadId,DBG_CONTINUE);
}


if ((DWORD) de.u.Exception.ExceptionRecord.ExceptionAddress > _GetProcAddress && (DWORD) de.u.Exception.ExceptionRecord.ExceptionAddress < _GetProcAddress + sizeof(patch))
{
printf("[+] Virus reached the breaker at 0x%.08x\n",de.u.Exception.ExceptionRecord.ExceptionAddress);


tc.ContextFlags = CONTEXT_CONTROL;
if (!GetThreadContext(pi.hThread, &tc))
{
printf("[-] Failed to get thread context, error: %d\n",GetLastError());
printf("[-] Disinfecting failed\n");
goto error_term;
}

ReadProcessMemory(pi.hProcess, (void*)tc.Esp, &stack_v, 4, NULL);
printf("[+] Virus request captured from 0x%.08x\n",stack_v);
printf("[+] Scanning backwards to 0x%.08x\n",upa);


while (1)
{
if (!ReadProcessMemory(pi.hProcess, (void*)stack_v, &ctx_fly, sizeof(ctx_sig), NULL)) break;
if (stack_v <= upa) break;

found = 1;
for (int ii=0; ii < sizeof(ctx_sig); ii++)
{
if (ctx_sig[ii] != ctx_fly[ii])
{
if (ctx_sig[ii] != 0x90)
{
found = 0;
break;
}
}
}

if (found == 1)
{
printf("[+] Orginal bytes were found at 0x%.08x\n",stack_v + 9);
printf("[!] Repairing the broken instruction.\n");
ReadProcessMemory(pi.hProcess, (void*)(stack_v + 9), (void*) sv, 5, NULL);
printf("[!] The file was disinfected!\n");
getch();
goto error_term;
}

stack_v--;
}

if (found == 0)
{
printf("[-] Error: no signature was found.\n");
printf("[-] Disinfecting failed\n");
goto error_term;
}

goto error_term;
}

}

}


ContinueDebugEvent(de.dwProcessId,de.dwThreadId,DBG_EXCEPTION_NOT_HANDLED);

}


error_term:
TerminateProcess(pi.hProcess,NULL);

error_di:
return TRUE;

}

标签:让人发疯的 | 浏览数(595) | 评论数(1) | 2007-04-05
FS选择子所索引的结构  

FS:[0x00]  Win9x and NT Current SEH frame
FS:[0x04]  Win9x and NT Top of stack
FS:[0x08]  Win9x and NT Current bottom of stack
FS:[0x10]  NT Fiber data
FS:[0x14]  Win9x and NT Arbitrary data slot
FS:[0x18]  Win9x and NT Linear address of TIB
FS:[0x20]  NT Process ID
FS:[0x24]  NT Current thread ID
FS:[0x2C]  Win9x and NT Linear address of the thread local storage array
FS:[0x30]  Pointer to PEB
FS:[0x34]  NT Current error number
FS:[0x38]  CountOfOwnedCriticalSections
FS:[0x3c]  CsrClientThread
FS:[0x40]  Win32ThreadInfo
FS:[0x44]  Win32ClientInfo[0x1f]
FS:[0xc0]  WOW32Reserved
FS:[0xc4]  CurrentLocale
FS:[0xc8]  FpSoftwareStatusRegister
FS:[0xcc]  SystemReserved1[0x36]
FS:[0x1a4] Spare1
FS:[0x1a8] ExceptionCode
FS:[0x1ac] SpareBytes1[0x28]
FS:[0x1d4] SystemReserved2[0xA]
FS:[0x1fc] GDI_TEB_BATCH
FS:[0x6dc] gdiRgn
FS:[0x6e0] gdiPen
FS:[0x6e4] gdiBrush
FS:[0x6e8] CLIENT_ID
FS:[0x6f0] GdiCachedProcessHandle
FS:[0x6f4] GdiClientPID
FS:[0x6f8] GdiClientTID
FS:[0x6fc] GdiThreadLocaleInfo
FS:[0x700] UserReserved[5]
FS:[0x714] glDispatchTable[0x118]
FS:[0xb74] glReserved1[0x1A]
FS:[0xbdc] glReserved2
FS:[0xbe0] glSectionInfo
FS:[0xbe4] glSection
FS:[0xbe8] glTable
FS:[0xbec] glCurrentRC
FS:[0xbf0] glContext
FS:[0xbf4] NTSTATUS
FS:[0xbf8] StaticUnicodeString
FS:[0xc00] StaticUnicodeBuffer[0x105]
FS:[0xe0c] DeallocationStack
FS:[0xe10] TlsSlots[0x40]
FS:[0xf10] TlsLinks
FS:[0xf18] Vdm
FS:[0xf1c] ReservedForNtRpc
FS:[0xf20] DbgSsReserved[0x2]
FS:[0xf28] HardErrorDisabled
FS:[0xf2c] Instrumentation[0x10]
FS:[0xf6c] WinSockData
FS:[0xf70] GdiBatchCount
FS:[0xf74] Spare2
FS:[0xf78] Spare3
FS:[0xf7c] Spare4
FS:[0xf80] ReservedForOle
FS:[0xf84] WaitingOnLoaderLock
FS:[0xf88] StackCommit
FS:[0xf8c] StackCommitMax
FS:[0xf90] StackReserve
???        MessageQueue

CLIENT_ID struct
    UniqueProcess
    UniqueThread
CLIENT_ID ends

标签:让人发疯的 | 浏览数(671) | 评论数(0) | 2007-01-09
闲着无聊写了个垃圾  

原理很简单,就用了三个记者API,完成列进程的任务。本想让他能检测隐藏进程,可是发现要利用驱动

.386p
.Model Flat,StdCall
Option CaseMap:None
;###########################################
;# API函数列表
;###########################################
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data

pformat db "%x",9,"%s",13,10,0
.code

start:
      mov eax,0xfffffff5
        push eax
        call GetstdHandle
        xor  eax,eax
        jz  proend
        mov [stdHandle],eax

        xor ebx,ebx
        push ebx
        push DWORD ptr 2
        call Createtoolhelp32snapshot
        inc eax
        jz  proend
      dec eax
        mov [snapHandle],eax

        mov [procentry.dwsize],sizeof PROCESSENTRY32

      push offset procentry
        push DWORD ptr [snaphandle]
        call Process32First

        xor  eax,eax
        jz   proend
     
loopfind:
      text eax,eax
        jz   findend
      
        push offset procentry.szExeFile
        push DWORD ptr procentry.th32ProcessID
        push offset pformat
        push offset buffer
        call wsprintf

        push offset buffer
        call lstrlen
      xchg eax,ecx
      push DWORD ptr 0
        push offset tmp
        push offset buffer
        push [stdHandle]
        call WriteConsole

        push offset procentry
        push [snapHandle]
        call Process32Next

        jmp  loopfind
findend:
        push [snapHandle]
          call closeHandle

proend:
      push dword ptr 0
        call ExitProcess
end start

(此人极懒,有的变量根本没声明,也没有调试,如果要测试自己声明下变量先)

标签:让人发疯的 | 浏览数(595) | 评论数(0) | 2006-12-29
病毒多态  

REQUIREMENTS:
-> Should know Inheritance in C++

That's it. But in the end I explain how the compiler implements polymorphism and
so knowledge of Assembly Language will be a great help in understanding
Polymorphism. Nevertheless I will still try to make the assembly explanation as
simple as possible.So even if you don't know Assembly,try understanding it.




I.                 WHAT IS POLYMORPHISM?


Polymorphism is in short the ability to call different functions by just using
one type of function call.It is a lot useful since it can group classes and
their functions together.Polymorphism is the most important part of Object-
Oriented Programming. Some people feel that if they have an idea of what classes
are they have stepped in the object-oriented world.But this is not true.
Polymorphism is the core of object-oriented programming and if anybody stops
here he's missing out the best part of Object Oriented Programming(OOP).All this
may seem a lot hard to understand but read on......you'll understand better as
you keep reading.


Let us now try to understand polymorphism with the help of an example.Suppose we
want to draw a picture consisting of circles,squares,lines and triangles.So we
can make a class Shape and create an instance of it like this:
    Shape *s[100];

Now all the addresses of the objects of the other classes(line,circle etc.) are
stored in the Shape Array.And then to draw the Picture all we have to do is this:
  for(int i=0;i<=100;i++)
    s->draw();

Now as the loop runs different draw functions of each class is called. This is
great because:
i. Functions from different classes are executed through the same function call.
i. The Array s[] has been defined to contain shape pointers and not square or
  triangle pointers.

This can be done by using Virtual Functions.



II.                 VIRTUAL FUNCTIONS????????

The Literal Meaning of Virtual means to appear like something while in reality
it is something else ie. when virtual functions are used, a program appears to
call a function of one class but actually it may be calling a function from
another class.In the previous example draw() is a virtual function since it
calls different draw functions from different classes by using the same function
call draw();


Now how do we know which version of draw() would be called during execution?
Which draw() function would get used depends on the contents of s
.But for
this polymorphic approach to work we must satisfy the following conditions:
->The Base class must contain a draw() function which is declared virtual.
->All other classes(line,circle etc.) should be derived from the base class.


Well, all this may be hard to understand in just one go so we'll start using
programs that'll help us understand better.Here's the First One.

#include <iostream.h>

class base                 //Base Class
{
public:
  void func()
  {
  cout<<"In base::func()\n";
  }
};

class d1:public base               // Derived Class 1
{
public:
  void func()
  {
  cout<<"In d1::func()\n";
  }
};

class d2:public base   // Derived Class 2
{
public:
  void func()
  {
  cout<<"In d2::func()\n";
  }
};

void main()
{
d1 d;
base *b=&d;
b->func();
d2 e;
b=&e;
b->func();
}

Run this program and you would see that the output would be:
In base::func()
In base::func()

Shouldn't this statement give an error? (b=&e;) No. Since the compiler allows a
pointer of a base class to accept addresses of derived class objects.This is
known as UPCASTING.Here the Compiler looks at the type of pointer b and since it
belongs to the base class it calls the base class function.

But now, let's make a slight modification in our program. Precede the
declaration of func() in the base class with the keyword virtual so that it
looks like this:

virtual void func()
{
  cout<<"In base::func()\n";
}


Now Compile and Run the Program. Now the Output is:
In d1::func()
In d2::func()

This time the Compiler looks at the contents of the pointer instead of it's type.
Hence since addresses of objects of d1 and d2 classes are stored in *b the
respective func() is called.But this way how does the compiler know which
function to compile when it doesn't know which object's address 'b' might
contain?Which version does the compiler call?

Actually even the compiler does not know which function to call at compile-time.
Hence it decides which function to call at run-time with the help of a table
called VTABLE. Using this table the compiler finds what object is pointed by
the pointer b and then calls the appropriate function. VTABLE is explained later.

The method by which the compiler decides which function to call at run-time is
known as late-binding or dynamic-binding. It slows down the program but makes it
a lot more flexible.

III.             PURE VIRTUAL FUNCTIONS


Now we realise that since the base class virtual function never gets called
anyway we'd better keep it's body blank.But there's a better way to do this.
We can change the virtual function func() in the base class to the following:
virtual void func()=0;

The =0 is not an assignment operator here but it is just a way of telling the
compiler that the function has no body.But there is another side of this. An
object of a class which contains a pure virtual function cannot be created.It
seems logical enough ie. If you have classes triangle,square,circle derived from
shape class we wouldn't want to make an object of the shape class.Hence the
shape class should be provided with a pure virtual function.If you even try to
create an object of a class containing a pure virtual function the compiler
would report an error even pointing out which pure virtual function prevents you
from creating an object.


IV.                 HOW VIRTUAL FUNCTIONS WORK

Using Virtual Functions is just one part of polymorphism and knowing how they
work completes the other half.When the keyword 'virtual' is inserted in the
declaration of the function the compiler inserts all mechanisms in the program
to use Virtual Functions. Each Class has a VTABLE that stores the functions that
it can access and Each class contains a VPTR which can access the VTABLE.Look at
this program and the table below it and you will understand the VTABLE and the
VPTR.


#include <stdio.h>


class item
{
public:
  virtual void price()
  {
    printf("In item::price()\n");
  }
  virtual void type()
  {
    printf("In item::type()\n");
  }
  void display();
};
void item::display(){printf("In item::display()\n");}

class microwave:public item
{
public:
  void price()
  {
    printf("Microwave::Price()\n");
  }

  void type()
  {
    printf("Microwave::type()\n");
  }
};

class computer:public item
{
public:
  void price()
  {
    printf("Compuer::Price()\n");
  }
};

class radio:public item
{
public:
  void type()
  {
    printf("radio::type()\n");
  }
};

void main()
{
microwave m1;
computer c1;
radio r1;

item *i=&m1;
i->price();
i->type();
printf("\n");

i=&c1;
i->price();
i->type();
i->display();
printf("\n");

i=&r1;
i->price();
i->type();
printf("\n");

microwave m2;
i=&m2;
i->price();
i->type();
i->display();
printf("\n");
}

The Output of this Program would be:

Microwave::Price()
Microwave::type()

Compuer::Price()
In item::type()
In item::display()

In item::price()
radio::type()

Microwave::Price()
Microwave::type()
In item::display()

Now here is how the VTABLE of each class Looks Like:
-------------------------------------------------------------------------------|
ITEM POINTERS   |   OBJECTS       |           VTABLES           |
-------------------------------------------------------------------------------|
i-------------> |   item{VPTR}----> |     &item::price()             |
          |               |     &item::type()             |
-------------------------------------------------------------------------------|
          |               |                           |
i-------------> |microwave m1,m2{VPTR}|     &microwave::price()         |
          |               |     &microwave::type()         |
-------------------------------------------------------------------------------|
          |               |                           |
i-------------> | computer c1{VPTR}-> |     &computer::price()         |
          |               |     &item::type()             |
-------------------------------------------------------------------------------|
          |               |                           |
i-------------->| radio r1{VPTR}----> |     &item::price()             |
          |               |     &radio::type()             |
-------------------------------------------------------------------------------|


First the VPTR Pointer is initialised to it's proper VTABLE by the contructor
which is automatically done by the compiler.When a Virtual Function is being
called the VPTR looks up the VTABLE and calls the virtual function.If the
function is not present in the VTABLE [like here display()] then the function of
the base class is called. So everywhere where the display function is called
item::display() is called everytime.No matter how many objects of a class are
created they all point to the same VTABLE of the class.


V.             ARE VIRTUAL FUNCTIONS OPTIONAL?

Normal Function calls are called by the Assembly instruction 'call' while
virtual functions require complex instructions. This takes up code space as well
as execution time.

Virtual Functions reduce the code's speed. Some languages like SmallTalk perform
Late Binding everytime a function is called and hence SmallTalk Programs aren't
fast enough. But C++ is a Superset of C where Efficiency is important and hence
C++ allows both static binding as well as late binding. The default convention
used is static binding so that there is no loss in speed.

Don't stop using Virtual Functions in your classes just because they reduce
execution speed. Infact it makes it easier to manage and code and it's
advantages are more than it's disadvantages. So wherever possible use Virtual
Functions in your classes.


VI.                   MISCELLENEOUS

1) If a Virtual Function is called within a derived classes constructor or
  destructor then the derived function is always called.

2) If b is a base class pointer and d is a derived class pointer then b=d will
  copy only the base class contents and remove the derived class contents.This
  is known as Object Slicing and should be avoided.

3) For a Virtual Function to work the function must be present in tha base
  class even though it is declared virtual in the derived class.

4) Virtual Destructors can also be used and they allow execution of the derived
  destructor first and then it calls itself.
 

VII.                   VIRTUAL BASE CLASSES


Consider a situation when a 'base' class has two classes derived from it.For
example derived1 and derived2.
Suppose we create another class which derives itself from both the derived
classes ie. derived3.Now suppose a member function of derived3 wants to access
data or functions in a base class.Since derived1 and derived2 are are derived
from base each inherits a copy of base.This copy is referred to as a subobject.
Now when derived3 refers to the data in the base class, which of the two copies
should it access? The compiler notices this ambiguous situation and reports an
error. To get rid of this we should make derived1 and derived2 as virtual base
classes.This is shown in the following program.

#include <iostream.h>

class base
{
  protected:
  int data;
 
  public:
  base()
  {
  data=10;
  }
};

class derived1 : virtual public base
{};

class derived2 : virtual public base
{};

class derived3 : public derived1,public derived2
{
  public:
  int getdata()
  {
    return data;
  }
};

void main()
{
derived3 d3;
int val=d3.getdata();
cout<<val<<endl;
}

Using the keyword virtual in the two classes derived1 and derived2 makes them
share a single subobject of the base class hence eliminating all ambiguity since
there is only one subobject for derived3 to access.Hence derived1 and derived2
are known as virtual base classes.



VIII.               VTABLE COMPILATION PROOF
    THIS PROGRAM IS COMPILED BY BORLAND C++ 5.02
Lot of people know that the compiler uses a VTABLE to implement Virtual
Functions but few get to see the actual code that the compiler generates.To save
space I shall Compile the same program which uses the item,microwave,computer
and radio class and explain how the compiler implements Virtual Functions. I
have used IDA Pro to disassemble this program. Here is the disassembled listing
followed by the explanation. I have included line numbers so that I can just
refer to the line numbers while explaining how the program works.


;                   THE FUNCTION main()
_main     proc near

m2_VPTR     = dword   ptr -10h
r1_VPTR     = dword   ptr -0Ch
c1_VPTR     = dword   ptr -8
m1_VPTR     = dword   ptr -4
argc     = dword   ptr 8
argv     = dword   ptr 0Ch
envp     = dword   ptr 10h

1       push   ebp
2     mov   ebp, esp
3     add   esp, 0FFFFFFF0h   ; 16 bytes allocated on   the stack
4     push   ebx     ; Register Saved
5     mov   [ebp+m1_VPTR], offset item_VTABLE
6     mov   [ebp+m1_VPTR], offset microwve_VTABLE
7     mov   [ebp+c1_VPTR], offset item_VTABLE
8     mov   [ebp+c1_VPTR], offset computer_VTABLE
9     mov   [ebp+r1_VPTR], offset item_VTABLE
10     mov   [ebp+r1_VPTR], offset radio_VTABLE
11     lea   ebx, [ebp+m1_VPTR]
12     push   ebx     ; this*   pushed
13     mov   eax, [ebx]
14     call   dword ptr [eax]   ; Calls   microwve_price
15     pop   ecx     ; 4 bytes freed   used up   by this*
16     push   ebx     ; this*   pushed
17     mov   edx, [ebx]
18     call   dword ptr [edx+4] ; Calls microwve_type
19     pop   ecx     ; 4 bytes freed   used up   by this*
20     push   offset newline   ; __va_args
21     call   _printf
22     pop   ecx     ; 4 bytes cleared used up by argument
23     lea   ebx, [ebp+c1_VPTR]
24     push   ebx     ; this*   pushed
25     mov   eax, [ebx]
26     call   dword ptr [eax]
27     pop   ecx
28     push   ebx
29     mov   edx, [ebx]
30     call   dword ptr [edx+4]
31     pop   ecx
32     push   ebx
33     call   item_display
34     pop   ecx
35     push   offset newline1   ; __va_args
36     call   _printf
37     pop   ecx
38     lea   ebx, [ebp+r1_VPTR]
39     push   ebx
40     mov   eax, [ebx]
41     call   dword ptr [eax]
42     pop   ecx
43     push   ebx
44     mov   edx, [ebx]
45     call   dword ptr [edx+4]
46     pop   ecx
47     push   offset newline2   ; __va_args
48     call   _printf
49     pop   ecx
50     mov   [ebp+m2_VPTR], offset item_VTABLE
51     mov   [ebp+m2_VPTR], offset microwve_VTABLE
52     lea   ebx, [ebp+m2_VPTR]
53     push   ebx
54     mov   eax, [ebx]
55     call   dword ptr [eax]
56     pop   ecx
57     push   ebx
58     mov   edx, [ebx]
59     call   dword ptr [edx+4]
60     pop   ecx
61     push   ebx
62     call   item_display
63     pop   ecx
64     push   offset newline3   ; __va_args
65     call   _printf
66     pop   ecx
67     pop   ebx
68     mov   esp, ebp
69     pop   ebp
70     retn
_main     endp

item_price   proc near         ; Function item::price()
1     push   ebp
2     mov   ebp, esp
3     push   offset aInItemPrice ;__va_args
4     call   _printf
5     pop   ecx
6     pop   ebp
7     retn
item_price   endp


radio_type   proc near           ;   Function radio::type()
1     push   ebp
2     mov   ebp, esp
3     push   offset aRadioType ; __va_args
4     call   _printf
5     pop   ecx
6     pop   ebp
7     retn
radio_type   endp


computer_price   proc near           ; Function computer::price()
1     push   ebp
2     mov   ebp, esp
3     push   offset aCompuerPrice ; __va_args
4     call   _printf
5     pop   ecx
6     pop   ebp
7     retn
computer_price   endp


item_type   proc near           ; Function item::type()

1     push   ebp
2     mov   ebp, esp
3     push   offset aInItemType ; __va_args
4     call   _printf
5     pop   ecx
6     pop   ebp
7     retn
item_type   endp


microwve_price   proc near           ;Function microwave::price()
1     push   ebp
2     mov   ebp, esp
3     push   offset aMicrowavePrice ; __va_args
4     call   _printf
5     pop   ecx
6     pop   ebp
7     retn
microwve_price   endp


microwve_type   proc near             ;Function microwave::type()
1     push   ebp
2     mov   ebp, esp
3     push   offset aMicrowaveType ;   __va_args
4     call   _printf
5     pop   ecx
6     pop   ebp
7     retn
microwve_type   endp


;                   THE DATA   SECTION


aInItemDisplay   db 'In item::display()',0Ah,0
newline     db 0Ah,0
newline1   db 0Ah,0
newline2   db 0Ah,0
newline3   db 0Ah,0

aInItemPrice   db 'In item::price()',0Ah,0
aRadioType   db 'radio::type()',0Ah,0
aCompuerPrice   db 'Compuer::Price()',0Ah,0
aInItemType   db 'In item::type()',0Ah,0
aMicrowavePrice   db 'Microwave::Price()',0Ah,0
aMicrowaveType   db 'Microwave::type()',0Ah,0

;                   THE   VTABLES

radio_VTABLE   dd offset item_price
    dd offset radio_type

computer_VTABLE   dd offset computer_price
    dd offset item_type

item_VTABLE   dd offset item_price
    dd offset item_type

microwve_VTABLE   dd offset microwve_price
    dd offset microwve_type
   
   


----------------------------EXPLANATION-----------------------------------------

For those who know nothing about Assembly but still dared to read till here
should remember that in Assembly code anything after the semicolon ';' is a
Remark. So between code I have inserted remarks so that it is easier to read.

Since we did not include the constructor in our code the compiler automatically
inserts it between the main() section.Hence we can see in LINE 5. that m1_VPTR
is first initialised to the VTABLE of item. Then in the next LINE m1_VPTR points
to the address of the VTABLE of Microwave class.The same process continues till
LINE 9.

Now in LINE 13. EAX contains the address pointed to by EBX ie. microwave_VTABLE.
In LINE 14. it calls the function which is located at the address of eax ie.
microwave::price(). This is the call of a virtual function.Look through the data
Section and see how the VTABLES are set.

In LINE 33. there is a straight-forward call to item::display() and this is how
a non-virtual function is called. Now compare the calling process of a non-
virtual function to that of a virtual function. You will notice that the calling
of a virtual function includes the following process:
1) Initialise the VPTR to that of the Base class VTABLE
2) Set the VPTR to the Derived class VTABLE
3) Load the address of the VTABLE in a Register
4) Call the Function located at the address pointed to by the VTABLE

But you require just one step to call a non-virtual function ie. the call
instruction followed by the function name.

You should notice that the other microwave object also points to the same VTABLE
but has a different VPTR. Each Class has it's own VTABLE and is shared among all
VPTR's of the Same class.

In LINE 30. the instruction call dword ptr [edx+4] calls the function located
at the (address+4 bytes) pointed by the EDX Register. This means that the 2nd
Function in the VTABLE is called.

Notice that in the VTABLE of the radio class the address of item::price() is
present.I hope you understand and appreciate the implementation of virtual
functions by the compiler.

This is the end of our tutorial. I hope you use Virtual Functions in your
programs since it is easier to code your programs using these functions. If you
have any doubts regarding Polymorphism feel free to contact me via email at
born2c0de@hotmail.com

标签:让人发疯的 | 浏览数(537) | 评论数(0) | 2006-12-19
基于进程的几个API函数  

照相的:

HANDLE WINAPI
CreateToolhelp32Snapshot( DWORD dwFlags, DWORD th32ProcessID );

The snapshot taken by this function is examined by the other tool help functions to provide their results. Access to the snapshot is read only. The snapshot handle acts like an object handle and is subject to the same rules regarding which processes and threads it is valid in.

To enumerate the heap or module states for all processes, specify TH32CS_SNAPALL and set th32ProcessID to zero. Then, for each additional process in the snapshot, call CreateToolhelp32Snapshot again, specifying its process identifier and the TH32CS_SNAPHEAPLIST or TH32_SNAPMODULE value.


 

跟踪的:


BOOL WINAPI Process32First(

  HANDLE hSnapshot,
LPPROCESSENTRY32 lppe
);

The calling application must set the dwSize member of PROCESSENTRY32 to the size, in bytes, of the structure. Process32First changes dwSize to the number of bytes written to the structure. This will never be greater than the initial value of dwSize, but it may be smaller. If the value is smaller, do not rely on the values of any members whose offsets are greater than this value.

To retrieve information about other processes recorded in the same snapshot, use the Process32Next function.


狗仔队的助手:


BOOL WINAPI Process32Next( HANDLE hSnapshot, LPPROCESSENTRY32 lppe );


Remarks

To retrieve information about the first process recorded in a snapshot, use the Process32First function.


 

标签:让人发疯的 | 浏览数(506) | 评论数(0) | 2006-12-19
  • 共17文章
  • 1
  • 2
  • 3
  • >

Powered by Haiwit