[原创]C# 与 汇编 的一次亲密接触。

废话不讲,转入正题!

前不久,有位网友在MSN上问我:如何解除被独占打开文件的锁定?
虽然从ring0层可以做到更加Power的处理,但是相对繁琐。
权衡之后,我决定在ring3层解决这个问题。经过网上的一番搜
索之后,写了一个简单的exe程序。后来略觉"简陋",遂决定加上
GUI。写win32界面不是汇编的强项,于是决定用.Net中的C#来写。

C#的高级语法对于数值运算、字符串、图形界面的处理简单方便;
而汇编对于程序性能优化、体积精简、低层代码可控性又得心应手。
两者结合使用,可以达到扬长避短的作用。和以前我用VB   +   ASM
的花哨界面不同,这次我力图做到界面最精简(当然还是有点花哨,呵呵)
,先做一个DEMO,由于才学C#不久,加上水平有限,可能有很多纰漏和
错误,以及一些还可以优化的地方,希望各位不吝指出,多谢了。

截图:

 

 

 

 

 

 

[细节&要点]

由文件句柄得到文件的名称,还可以用内存影射文件的方法,但有局限性。

Assembly code

    _GetFileNameByHandle proc uses esi edi ebx _handle,_hProcess,/
    _lpFileName,/
    _lpProcessName
    ;_lpstOpenFile

    local @stFI:_FileInfo,@hThread:dword

    mov eax,_handle
    mov @stFI.Handle,eax

    invoke RtlZeroMemory,addr @stFI.FInfo.FileNameW,/
    MAX_PATH * 2

    invoke CreateThread,NULL,0,addr _WorkThread,/
    addr @stFI,0,NULL
    mov @hThread,eax

    invoke WaitForSingleObject,@hThread,100

    .if eax == WAIT_TIMEOUT
    invoke TerminateThread,@hThread,0
    .endif

    invoke CloseHandle,@hThread

    invoke RtlZeroMemory,addr buf,/
    sizeof buf

    invoke GetProcessImageFileNameA,_hProcess,addr buf,/
    sizeof buf

    invoke _GetProcessShortName,addr buf

    invoke lstrcpy,_lpProcessName,addr buf

    mov eax,@stFI.FInfo.FileNameLength

    .if eax != 0
    push eax

    invoke RtlZeroMemory,addr buf,/
    sizeof buf

    pop eax
    shr eax,1

    invoke WideCharToMultiByte,CP_ACP,0,/
    addr @stFI.FInfo.FileNameW,eax,/
    addr buf,MAX_PATH,NULL,NULL

    invoke lstrcpy,_lpFileName,addr buf
    .else
    invoke lstrcpy,_lpFileName,addr szDefaultFileName
    .endif

    ret

    _GetFileNameByHandle endp

有些"文件"(实际是管道)会造成操作挂起,遂用线程处理之:

Assembly code

    _WorkThread proc _lpFileInfo
    local IoStatus:IO_STATUS_BLOCK

    assume esi:ptr _FileInfo
    mov esi,_lpFileInfo

    invoke NtQueryInformationFile,[esi].Handle,addr IoStatus,/
    addr [esi].FInfo,sizeof(_FileInfo)-sizeof(dword),/
    FileNameInformation

    assume esi:nothing
    ret

    _WorkThread endp

关于C#与汇编的接口兼容问题,取出一个结构说明:
在C#中:

C# code

    private struct _stOpenFile
    {
    public uint lpProcessName;
    public uint lpFileName;
    public uint ProcessID;
    public uint Flags;
    public uint hFile;
    public uint GrantedAccess;
    }

在   asm   中:

Assembly code

    _stOpenFile struct

    lpProcessName dd ?
    lpFileName dd ?
    ProcessID dd ?
    Flags dd ?
    hFile dd ?
    GrantedAccess dd ?
    _stOpenFile ends

在C#中调用方法:

C# code

    private void btnFind_Click(object sender, EventArgs e)
    {
    StringBuilder szTmp = new StringBuilder(256);

    string FileName, ProcessName;

    _stOpenFile stOP = new _stOpenFile();

    this.btnFind.Enabled = false;

    this.lstvewFind.Items.Clear();
    this.lstvewFind.Refresh();

    unsafe
    {
    byte[] szProcessName = new byte[256];
    byte[] szFileName = new byte[256];

    fixed (byte* lpPN = szProcessName)
    fixed (byte* lpFN = szFileName)
    {
    stOP.lpProcessName = (uint)lpPN;
    stOP.lpFileName = (uint)lpFN;

    while (EnumAllOpenFile(ref stOP) == true)
    {
    ProcessName = Encoding.Default.GetString(szProcessName).Trim('/0');
    FileName = Encoding.Default.GetString(szFileName).Trim('/0');

    if ((FileName.ToString().Length == 0) && (ProcessName.ToString().Length == 0))
    {
    Array.Clear(szProcessName, 0, 256);
    Array.Clear(szFileName, 0, 256);
    continue;
    }

    if (FileName.ToString().ToLower() == this.txtFind.Text.ToString().ToLower())
    {
    this.lstvewFind.Items.Add(ProcessName.ToString()).SubItems.AddRange(new string[] {
    FileName.ToString(),stOP.hFile.ToString(),stOP.Flags.ToString(),
    "0x"+Convert.ToString(stOP.GrantedAccess,16),stOP.ProcessID.ToString()});
    this.lstvewFind.Refresh();
    }
    else
    {
    szTmp.Remove(0, szTmp.Length);
    szTmp.Append(FileName.ToString());
    GetShortName(szTmp);
    if (szTmp.ToString().ToLower() == this.txtFind.Text.ToString().ToLower())
    {
    this.lstvewFind.Items.Add(ProcessName.ToString()).SubItems.AddRange(new string[] {
    FileName.ToString(),stOP.hFile.ToString(),stOP.Flags.ToString(),
    "0x"+Convert.ToString(stOP.GrantedAccess,16),stOP.ProcessID.ToString()});
    this.lstvewFind.Refresh();
    }
    }
    Array.Clear(szProcessName, 0, 256);
    Array.Clear(szFileName, 0, 256);
    }
    }
    }
    MessageBox.Show("Total Find " + lstvewFind.Items.Count.ToString() + " Open Files !");

    this.btnFind.Enabled = true;
    }

    上面应该可以再大幅度优化,请各位不吝指出,多谢。


				
时间: 2024-08-29 15:43:16

[原创]C# 与 汇编 的一次亲密接触。的相关文章

嘀咕亲密接触麦当劳 LBS应用渐趋高潮

   时近年底,无论你是身处干旱的北方还是冰冻的南方,忙碌了一年的我们终于可以放松疲惫的身心,到路边街旁悠然散步,走走停停.如果你此时此刻行走在广东一些地区的地铁站.的士亭前,一定能看到一些大大的海报或者灯箱广告,诸如"100000个麦当劳美味派免费大赠送"的字样,吸引着路人的眼球.本来以为这只不过是传统商家的传统营销手段,可稍一驻足发现,这竟然是麦当劳与嘀咕网的合作.这次合作不仅是LBS签到服务商嘀咕与传统餐饮巨头麦当劳的第一次亲密接触,是二者携手对传统营销模式的创新,而且是有史以来

从零开始与网站开发亲密接触

从零开始与网站开发亲密接触 去年我接手第一个网站项目开发时,并没有做网站的经验,只能试着按照以前我参与做Microsoft Office时的方法来做: 首先是打造一个便于公司内部沟通交流的内部网,其中包含"传统软件"研发需要的三个工具:文档库(存放公司各项目的文档).CVS(保存项目的各种源代码).BugFree(记录项目的各种缺陷). 然后,抓住"需求.开发.测试"三个环节: 1 要做好规划.明确需求.为什么要做这个网站.要达到什么目标?特别是需求,要详细到每个页

Photoshop教程02:亲密接触Photoshop6

教程 跟Photoshop6约会结束来,想不想再来一次亲密接触呢?不要着急,往下看! 一目了然的选项栏 Photoshop6.0的操作界面有了较大的改变,重要的变化是添加了选项栏,其功能相当 图2-01 画笔调板,在Photoshop6.0画笔调板已经成为画笔工具的一个选项,画笔的设置和各种选项也在画笔工具的选项栏中完成,如图2-02所示. 图2-02 图像以前的编辑菜单下的数字变形命令指定图像旋转和缩放比例变为变形命令的选项栏来完成,如图2-03所示. 图2-03 制作优秀的网络图像 各位是不

亲密接触ASP.Net(16) Cookie

Cookie Cookie的用法也和ASP中差不多.比如我们建立一个名为aspcn,值为飞刀的cookie HttpCookie cookie = new HttpCookie["aspcn"];cookie.Value = "飞刀";Response.AppendCookie(cookie); 我们取出Cookie值也很简单 HttpCookie cookie = Request.Cookies["aspcn"];cookieValue = c

亲密接触Redis-第三天(Redis的Load Balance)

前言 上两天讲述了Redis的基本搭建和基于HA的集群布署方式以及相关的策略和注意点.今天开始讲述Redis的Cluster功能,而这块目前来说网上资料不是太全,就算有1,2篇也只是单讲服务端的搭建也并未提及相关的客户端怎么和Redis Cluster间的调用问题. 我们今天要讲述的Redis Cluster是真正的Load Balance,它和Sentinel不一样,Sentinel虽然也叫集群,可是它是一种HA策略即High Available或者又通俗的被称为"灾难转移"策略.

AWS F1 正式上线,深度解析 FPGA 与公有云的亲密接触

1. 背景 历经近 5 个月的邀请内测,Amazon AWS 于 4 月 20 日宣布 FPGA EC2 实例 F1 正式上线.就在 F1 内测公布后这短短几个月时间,国内互联网巨头 BAT 加华为纷纷借势宣布开展 FPGA 云加速器业务,这一波异构计算之风势头之猛可见一斑. 其实,FPGA 以其高能效和可重编程的优势,在大型互联网企业内部早有应用并逐渐成为常态.例如媒体压缩,加解密,AI,大数据处理等领域,FPGA 方案较传统 CPU 和 GPGPU,往往可达到几倍甚至几十倍的能效提升.然而过

我与鸟哥 Yar 的亲密接触

模块越来越多,业务越来越复杂,RPC 就上场了,在 PHP 的世界里,鸟哥的作品一直备受广大网友的青睐.下面一起学习下鸟哥的 PRC 框架 Yar . 揭开 Yar 神秘面纱 RPC 采用客户端/服务器模式.首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息.在服务器端,进程保持睡眠状态直到调用信息的到达为止.当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行.这和

《SAP HANA平台应用开发》—第2章2.2节第一次亲密接触

2.2 第一次亲密接触2.2.1 几个系统用户SAP HANA服务器安装好以后,表2-1中所示的3个用户都是需要提交到SAP HANA系统的管理和运维人员.表2-1 重要的用户用户名 类型 说明root OS用户 SUSE Linux操作系统root用户,用于软件升级.安装等adm OS用户 这个SAP HANA系统实例的管理用户system HANA系统用户 SAP HANA数据库的管理员 root用户是SAP HANA软件上运行的SUSE Linux操作系统的用户,在安装SAP HANA软件

要赚钱 就要让网站与传统亲密接触

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断淘宝客 站长团购 云主机 技术大厅 网站命根是来自人们生活的需求,只有响应源自生活的呐喊,网站才会受到人们的认可,也只有借鉴传统的力量它才有原始的生命.网络需要创意创新,因为它区别于传统却要补充.改变.颠覆.代替传统,使网络变成新传统. 有很多人总会问,现在做什么样的网站或者做什么类型的网站能赚钱有前途.这个就等于向别人问他自己的价值观是什么了,这个其他人怎么会知道!每