使用CBrother的CLIB库调用windows的API

2.1.0版本CBrother加入了CLib库,最新需要写一个工具,根据路径查杀一个Windows进程,研究了一下,CLib库的用法,感觉还是比较灵活的。

首先我要明确每一个API在系统的哪一个dll里面,我一般都是去微软官网查这个API。(https://docs.microsoft.com/zh-cn/windows/win32/api/),

比如我查OpenProcess这个API,查到如下内容

在Kernel32.dll里面,其他用到的API也都是这样获取信息,下面就可以写代码了。

 import CBCLib.code

 var g_kernel32_init = false;                    //kernel32.dll 是否初始化
var g_kernel32 = null; //Kernel32.dll 句柄
var g_kernel32_OpenProcess = null; //OpenProcess函数
var g_kernel32_CloseHandle = null; //CloseHandle函数
var g_kernel32_GetModuleFileNameExA = null; //GetModuleFileNameExA函数
var g_kernel32_GetLogicalDriveStringsA = null; //GetLogicalDriveStringsA函数
var g_kernel32_QueryDosDeviceA = null; //QueryDosDeviceA函数 var g_psapi_init = false; //psapi.dll 是否初始化
var g_psapi = null; //psapi.dll 句柄
var g_psapi_GetProcessImageFileNameA = null; //GetProcessImageFileNameA函数 const MAX_PATH = 1024; //获取kernel32.dll里面的函数
function initkernel32()
{
if (g_kernel32_init)
{
return;
} g_kernel32_init = true; g_kernel32 = new CLib("kernel32.dll");
if(!g_kernel32.load())
{
print "kernel32.dll load err!";
return;
} //根据函数原型和CLib库类型对应关系写参数列表
g_kernel32_OpenProcess = g_kernel32.findFunc("OpenProcess","pointer","int","bool","int");
g_kernel32_CloseHandle = g_kernel32.findFunc("CloseHandle","bool","int");
g_kernel32_GetModuleFileNameExA = g_kernel32.findFunc("K32GetModuleFileNameExA","int","pointer","pointer","pointer","int");
g_kernel32_GetLogicalDriveStringsA = g_kernel32.findFunc("GetLogicalDriveStringsA","int","int","pointer");
g_kernel32_QueryDosDeviceA = g_kernel32.findFunc("QueryDosDeviceA","int","string","pointer","int");
}

我还用到了psapi.dll里面的函数

 //Psapi.dll里面的函数
function initpsapi()
{
if (g_psapi_init)
{
return;
}
g_psapi_init = true; g_psapi = new CLib("Psapi.dll");
if (!g_psapi.load())
{
print "Psapi.dll load err!";
return;
} //根据函数原型和CLib库类型对应关系写参数列表
g_psapi_GetProcessImageFileNameA = g_psapi.findFunc("GetProcessImageFileNameA","int","pointer","pointer","int");
}

下面是根据进程pid获取进程路径

 const STANDARD_RIGHTS_REQUIRED = 0x000F0000;
const SYNCHRONIZE = 0x00100000;
function GetProcessPath(pid)
{
initkernel32(); //打开目标进程
var hProcess = g_kernel32_OpenProcess.callFunc(STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF,false,pid);
if (hProcess.isNull())
{
print "openprocess err! " + pid;
return;
} //构建一个buffer,GetModuleFileNameExA会把路径写进这个buffer里
var pathBuff = new CLibPointer();
pathBuff.malloc(MAX_PATH); var res = g_kernel32_GetModuleFileNameExA.callFunc(hProcess,null,pathBuff,MAX_PATH);
if(res > 0)
{
//GetModuleFileNameExA获取成功
res = pathBuff.readString();
}
else
{
//有些系统获取不成功,需要使用另外一种方法。32位程序获取64位进程也需要用这种方法。
res = GetProcessPathByPsapi(hProcess);
} //释放buffer
pathBuff.free(); //关闭目标进程句柄
g_kernel32_CloseHandle.callFunc(hProcess);
return res;
}

如果GetModuleFileNameExA获取失败了,需要使用GetProcessImageFileNameA获取dos路径,然后转化成绝对路径

 //使用GetProcessImageFileNameA获取进程路径
function GetProcessPathByPsapi(hProcess)
{
initkernel32();
initpsapi(); var newPath = "";
var tempBuff = new CLibPointer();
tempBuff.malloc(MAX_PATH);
var res = g_psapi_GetProcessImageFileNameA.callFunc(hProcess,tempBuff,MAX_PATH);
if(res > 0)
{
var driveStr = new CLibPointer();
driveStr.malloc(MAX_PATH);
//获取所有盘符
if(g_kernel32_GetLogicalDriveStringsA.callFunc(MAX_PATH,driveStr))
{
var dospath = tempBuff.readString();
var driveName = new CLibPointer();
driveName.malloc(MAX_PATH);
var copydriveStr = driveStr.copyAddr(); //遍历盘符,和DOS盘符名称对照
while (1)
{
var szDrive = copydriveStr.readString();
szDrive = strget(szDrive,0,2);
if(g_kernel32_QueryDosDeviceA.callFunc(szDrive,driveName,MAX_PATH))
{
var dname = driveName.readString();
var namelen = strlen(dname);
if(strnicmp(dname,dospath,namelen) == 0)
{
//对上了,说明就是这个路径
newPath = szDrive;
newPath += strget(dospath,namelen);
break;
} //盘符指针向前加4获取下一个盘符
copydriveStr.addAddr(4);
}
else
{
break;
}
} driveName.free();
}
driveStr.free();
} tempBuff.free();
return newPath;
}

下面就是在main函数使用

 var g_path = "E:\\111\\test.exe";       //进程路径
var g_name = "test.exe"; //进程名
function main(params)
{
//这个函数是CBrother提供的,根据进程名获取pid,存到array里
var pidarr = GetProcessByName(g_name);
for (var i = 0; i < pidarr.size() ; i++)
{
//根据pid获取进程路径
var path = GetProcessPath(pidarr[i]);
if (path == g_path)
{
//如果路径匹配上了,杀掉。这个函数也是CBrother提供的,根据进程ID查杀进程
KillProcessByID(pidarr[i]);
}
}
}

用法还是比较容易理解,只要你熟悉windows编程,那么CBrother可以做任意你想做的事情。

上面这个api的用法我已经把代码发给作者了,作者说后续会加入lib库里,后续慢慢扩展成所有的api,这样在windows下使用api的就更方便了。

使用CBrother的CLIB库调用windows的API的更多相关文章

  1. mfc 调用Windows的API函数实现同步异步串口通信(源码)

    在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信.串口通信方便易行,应用广泛. 一般情况下,工控机和各智能仪表通过RS485总线进行通信.RS485的通信方式是半 ...

  2. c运行时库,c标准库,Windows系统api的关系

    原文地址:http://blog.csdn.net/seastars_sh/article/details/8233324 C运行库和C标准库的关系 C标准库,顾名思义既然是标准,就是由标准组织制定的 ...

  3. python 中调用windows系统api操作剪贴版

    # -*- coding: utf-8 -*- ''' Created on 2013-11-26 @author: Chengshaoling ''' import win32clipboard a ...

  4. 善于 调用Windows API

    前一段时间看见别人做的一个自动填写信息并且点击登录的程序,觉得很有意思. 其实就是在程序中调用Windows的API,那么如何调用,下面就做个简单的介绍. 写的简单粗暴, 不喜轻喷. 0.首先引入名称 ...

  5. (Delphi) Windows 32 API程序设计目录

    这里所有程序均使用Delphi调用Windows 32 API方式实现,并不是使用VCL已经封装好的类实现的! (一)第一个窗口程序 01 创建第一个窗口.

  6. .NET 6学习笔记(4)——如何在.NET 6的Desktop App中使用Windows Runtime API

    Windows Runtime API是当初某软为了区别Win32 API,力挺UWP而创建的另一套Windows 10专用的API集合.后来因为一些原因,UWP没火.为了不埋没很有价值的Window ...

  7. Golang调用windows下的dll动态库中的函数

    Golang调用windows下的dll动态库中的函数 使用syscall调用. package main import ( "fmt" "syscall" & ...

  8. Golang调用windows下的dll动态库中的函数 Golang 编译成 DLL 文件

    Golang调用windows下的dll动态库中的函数 package main import ( "fmt" "syscall" "time&quo ...

  9. Python调用windows下DLL详解 - ctypes库的使用

    在python中某些时候需要C做效率上的补充,在实际应用中,需要做部分数据的交互.使用python中的ctypes模块可以很方便的调用windows的dll(也包括linux下的so等文件),下面将详 ...

随机推荐

  1. MySQL学习(一)索引的基本认识

    MySQL中,所有的数据类型都可以被索引,包括普通索引,唯一性索引,全文索引,单列索引,多列索引和空间索引等. 额外的:我已知的自动创建索引的时机:创建主键,唯一,外键约束的时候 一.索引简介 1.1 ...

  2. SVN应用

    一:从服务器上down资料 1.在电脑上安装SVN客户端 2.在电脑本地创建个文件夹作为版本库 3.进入xfssvn文件夹右击鼠标选择SVN Checkout或SVN Update 4.输入服务器中配 ...

  3. 第3章(1) Linux内核相关概念

    Linux内核的组成 1. Linux内核源代码的目录结构 arch:包含和硬件体系结构相关的代码,每种平台占一个相应的目录,如 i386.arm. arm64.powerpc.mips 等.Linu ...

  4. 单调队列与DP

    算是一个总结吧! 先来一个模板: TYVJ 1305 最大子序和 题目描述 输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大. 例如 1,-3,5,1,-2,3 当m ...

  5. Flink Connector 深度解析

    作者介绍:董亭亭,快手大数据架构实时计算引擎团队负责人.目前负责 Flink 引擎在快手内的研发.应用以及周边子系统建设.2013 年毕业于大连理工大学,曾就职于奇虎 360.58 集团.主要研究领域 ...

  6. .Net轻量状态机Stateless的简单应用

    对于大部分系统中流程的变更,是十分正常的事情,小到一个状态的切换,大到整个系统都是围绕业务流再走,复杂点的有工作流引擎,简单点的几个if/else收工,但是往往有那种,心有余而力不足的,比简单复杂,比 ...

  7. FormData交互以及Node multiparty插件的使用

    一.FormData FormData是ajax2.0里面添加的新特性. FormData的主要用途有两个: (1).将form表单元素的name与value进行组合,实现表单数据的序列化,从而减少表 ...

  8. (一) kinect概述

    Kinect可以进行身体节点定位,姿势定位,人脸识别等功能,在此先做简单介绍,后续主要介绍插件的应用,毕竟自己开发识别过程太消耗时间. (注1:Kinect官方虽然提供了Unity的APi,但是方便起 ...

  9. 服务器配置:ECS+Nginx+uWSGI+Flask——各部分详细介绍

    希望在阿里云ECS上搭建一个flask框架的web应用,经典的形式便是flask+uWSGI+nginx模式 服务器:CentOS 7.3 python版本:3.8.0 先贴一张全局图,这张图很清楚的 ...

  10. 省市区三级联动(vue)

    vue项目中使用到三级联动,现在自己实现一个三级联动,仅供大家参考一下,直接上代码. <template> <section class="container"& ...