hopy | 侯佩

大熊猫侯佩 ! 不要和偶比懒,偶懒得和你比 -_-b

hope yangID:mydo
41106次访问,排名2662好友57人,关注者108
asm & C
mydo的文章
原创 34 篇
翻译 0 篇
转载 20 篇
评论 90 篇
hopy|侯佩的公告

intel 还是 at&t ?这是个问题!

贪吃贪睡的大熊猫侯佩!


最近评论
chtitaxie:不错,相当好.
goho100:特别想学黑客技术,但是却什么都不懂,有劳费心了!
mldstk:wow power leveling
huyongzs:哇,厉害。
chenjava:高手,,可以把完整代码放出来吗?FarAddr是指向哪个地址的啊?
文章分类
收藏
    相册
    程人画册
    生随画册
    常逛网站
    aogo汇编站
    sourceforge
    Windows Sysinternals
    www.0ginr.com
    www.reactos.org
    www.rootkit.com
    个人电脑
    中国IT实验室
    中国电子顶级开发网
    安全焦点
    安全矩阵
    安徽机票网
    看雪论坛
    第8个男人
    邪恶八进制论坛
    驱动开发网
    高端调试
    朋友的blog(排名不分先后)
    Chen 的 blog
    信仰 的 blog
    兔子 的 blog
    十月印象 的 blog
    存档
    订阅我的博客
    XML聚合  FeedSky

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

    新一篇: [原创]另一种进入NT内核方法的汇编版本 | 旧一篇: [公告]汇编提问的智慧

    废话不讲,转入正题!

    前不久,有位网友在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;
        }

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

    [细节&要点2] 

    要   open   一些特权进程,需要DEBUG权限,否则无法枚举这些进程中
    的文件,遂首先打开DEBUG特权:


    Assembly code


    _EnableDebugPrivilege proc _isEnable
    local htoken:HANDLE
    local uid:LUID
    local tp:TOKEN_PRIVILEGES
    local isSuccess

    mov isSuccess,FALSE

    invoke GetCurrentProcess
    lea ebx,htoken
    invoke OpenProcessToken,eax,TOKEN_ADJUST_PRIVILEGES,\
    ebx
    invoke LookupPrivilegeValue,NULL,addr SE_DEBUG_NAME0,\
    addr uid

    mov tp.PrivilegeCount,1
    push uid.LowPart
    pop tp.Privileges[0].Luid.LowPart
    push uid.HighPart
    pop tp.Privileges[0].Luid.HighPart
    .if _isEnable
    mov tp.Privileges[0].Attributes,\
    SE_PRIVILEGE_ENABLED
    .else
    mov tp.Privileges[0].Attributes,0
    .endif

    invoke AdjustTokenPrivileges,htoken,FALSE,addr tp,\
    sizeof tp,NULL,NULL

    invoke GetLastError
    .if eax == ERROR_SUCCESS
    mov isSuccess,TRUE
    .endif

    invoke CloseHandle,htoken
    mov eax,isSuccess
    ret

    _EnableDebugPrivilege endp


    由于使用远线程(本来想用HOOK,但还是觉得远线简单   :)),所以
    要考虑重定位:


    Assembly code

    REMOTE_CODE_START equ this byte

    _lpCloseHandle dd ?

    _RemoteThread proc uses ebx edi esi _hFile

    call @F
    @@:
    pop ebx
    sub ebx,offset @B

    push _hFile
    mov eax,[ebx + _lpCloseHandle]
    ;mov eax,07c809b47h
    call eax
    ret

    _RemoteThread endp

    REMOTE_CODE_END equ this byte
    REMOTE_CODE_LENGTH equ offset REMOTE_CODE_END - offset REMOTE_CODE_START


    发表于 @ 2007年12月29日 09:13:00|评论(loading...)|

    新一篇: [原创]另一种进入NT内核方法的汇编版本 | 旧一篇: [公告]汇编提问的智慧

    评论

    #ttzyanswer 发表于2008-03-11 12:32:30  IP: 218.242.251.*
    拜托,内容的格式也太不工整了吧.就算是好文,这么不工整.想看得人也不爱看了.
    #mydo 发表于2008-03-16 14:56:54  IP: 60.166.248.*
    谢谢提醒。
    发表评论  


    登录
    Csdn Blog version 3.1a
    Copyright © hopy|侯佩