首页 文章 精选 留言 我的

精选列表

搜索[hook],共1793篇文章
优秀的个人博客,低调大师

Windows Hook

啥是windows的钩子?钩子故名思议就是在嵌入到正常执行程序的功能。对于windows来说,每个系统和应用程序之间的交互是使用消息机制来进行。比如点击应用程序上面的某个按钮,就是发送了事件给了应用程序。windows钩子的作用就是在事件发送给应用程序之前截获事件,先对事件做处理,然后有两个选择,可以继续抛出事件,也可以消灭时间。于是每个事件在windows上的相应都是一个事件处理链,没增加一个处理的应用程序就是给这个事件处理链增加一个链接点而已。 创建钩子 创建windows钩子就需要三个步骤: 1 创建钩子 2 相应钩子接收的事件 3 卸载钩子 window提供了钩子的几个接口: http://msdn.microsoft.com/en-us/library/windows/desktop/ms632589(v=vs.85).aspx 其中最需要关注的是几个: SetWindowsHookEx UnhookWindowsHookEx CallNextHookEx 分别是安装钩子,卸载钩子,执行下个钩子操作。执行的顺序如其名:先安装钩子,后处理事件,后调用下个钩子,最后卸载钩子。 一个个看着三个接口: SetWindowsHookEx 1 2 3 4 5 6 7 8 9 10 11 HHOOK WINAPI SetWindowsHookEx( _In_ int idHook, _In_ HOOKPROC lpfn, _In_ HINSTANCE hMod, _In_ DWORD dwThreadId ); 返回值是个HHOOK,就是钩子的唯一标识,类型在c#中是个int型,如果安装钩子成功,返回一个int,如果安装不成功,返回NULL。 参数: idHook idHook是个int类型,标识的是钩子的类型,比如7代表钩子监控鼠标事件,2代表键盘事件。这里不同的事件代表捕获不同的消息,所以后面的消息处理事件也会有不同(这里说的不同不是事件的参数个数和类型不同,而是参数值的含义不同)。好了,这里有个问题,如果我要监控所有事件有办法吗?有,你可以使用4(WH_CALLWNDPROC)来捕获所有消息。 lpfn lpfn是个注册回调事件,c#中可以使用delegate,这个事件大致是如下的接口: 1 2 3 4 5 6 7 8 9 LRESULT CALLBACK CallWndProc( _In_ int nCode, _In_ WPARAM wParam, _In_ LPARAM lParam ); 即有三个参数和一个返回值 nCode:说明下事件如何处理消息,一般如果nCode是小于0的,那么就说明这个注册事件不能做任何处理,应该把事件传递给下个钩子。为0或者其他值根据idHook有不同的含义。 wParam:一般说明这个事件消息的类型。 lParam:一般是指向一个包含具体事件的结构。 hMod hMod是个int类型,如果钩子的注册事件是由dll包含的话,值非零,如果是由当前进程包含的话,则设置为Intptr.Zero(NULL) dwThreadId dwThreadId也是说明这个钩子注册的回调事件的位置,如果是0的话,则注册的回调事件是在当前线程的。如果不是在当前的线程,则dwThreadId是非0 UnhookWindowsHookEx 1 2 3 4 5 BOOL WINAPI UnhookWindowsHookEx( _In_ HHOOK hhk ); 理解了SetWindowsHookEx之后,就很好理解UnhookWindowsHookEx了。 这里的HHOOK是SetWindowsHookEx函数的返回值,钩子的唯一标识。 返回的BOOL代表卸载钩子是否成功。 CallNextHookEx 1 2 3 4 5 6 7 8 9 10 11 LRESULT WINAPI CallNextHookEx( _In_opt_ HHOOK hhk, _In_ int nCode, _In_ WPARAM wParam, _In_ LPARAM lParam ); 这个函数是用来让事件随着钩子链继续执行下去的。一般在注册的回调事件中执行的,所以和注册的回调事件有点像。 hhk:HHOOK类型(int)代表钩子ID,但是实际上是被忽略的。 nCode,wParam,lParam具体的含义和注册回调函数是一样的。在使用的时候,只要将注册回调函数接受到的参数直接传递给CallNextHookEx就可以了。 windows钩子有什么作用? 借用msdn(http://msdn.microsoft.com/en-us/library/windows/desktop/ms644959(v=vs.85).aspx)上说的几个用途: 1 调试使用(可以监视传递给应用的消息) 2 作为宏使用。(你可以将你在windows的任何动作录制成宏) 3 监控F1动作来提供帮助。(很多应用上F1动作都是调出帮助信息的) 4 模拟键盘和鼠标操作 5 实现基于机器学习的应用(CBT computer-based training ) 本文转自轩脉刃博客园博客,原文链接:http://www.cnblogs.com/yjf512/archive/2013/05/13/3075179.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

实例讲解:React Hook的思考

翻译原文:https://wattenberger.com/blog/react-hooks React在一年前引入了hooks,对于许多开发人员来说,它们已经改变了我们的编码习惯,但我想谈一谈从React类组件切换到功能组件基本变化。 使用类组件,我们将更新放置在特定的生命周期事件中 ❝ 类组成中 ❞ classChartextendsComponent{componentDidMount(){//挂载时}componentDidUpdate(prevProps){if(prevProps.data==props.data)return//数据更新时}componentWillUnmount(){//卸载时}render(){return(<svgclassName="Chart"/>)}} 在功能组件中,我们改为使用useEffect挂钩在主要生命周期事件期间运行代码。 ❝ 功能组件中 ❞ constChart=({data})=>{useEffect(()=>{//挂载时//数据更新时return()=>{}},[data])return(<svgclassName="Chart"/>)} 此时,您可能在想:所以,useEffect() 这只是一种进入生命周期事件的新方法!但是这种理解是错误的! 嗯,让我们看一个具体的例子,看看有什么区别。例如,如果我们有一个计算量大的 getDataWithinRange()函数,该函数基于指定的函数返回经过过滤的数据集,该dateRange怎么办?因为getDataWithinRange()运行需要一些时间,所以我们希望将其存储在组件的state对象中,并且仅在dateRange发生更改时进行更新。 类组成: 对于生命周期事件,我们需要一站式处理所有更改。我们的想法如下所示: 当我们的组件加载时,以及props更改时(其实就是dateRange),就相对的更新data 大致如下: classChartextendsComponent{state={data:null,}componentDidMount(){constnewData=getDataWithinRange(this.props.dateRange)this.setState({data:newData})}componentDidUpdate(prevProps){if(prevProps.dateRange!=this.props.dateRange){constnewData=getDataWithinRange(this.props.dateRange)this.setState({data:newData})}}render(){return(<svgclassName="Chart"/>)}} 功能组成 在功能组件中,我们需要考虑哪些值保持同步。每次更新的流程更像以下语句: 保持dateRange同步data 大致如下: constChart=({dateRange})=>{const[data,setData]=useState()useEffect(()=>{//假设getDataWithinRange在外部定义了,暂时不考虑这个constnewData=getDataWithinRange(dateRange)setData(newData)},[dateRange])return(<svgclassName="Chart"/>)} 看到将变量保持同步的方式简单多了是吗?不仅仅是代码量减少了! 类组成 classChartextendsComponent{state={data:null,}componentDidMount(){constnewData=getDataWithinRange(this.props.dateRange)this.setState({data:newData})}componentDidUpdate(prevProps){if(prevProps.dateRange!=this.props.dateRange){constnewData=getDataWithinRange(this.props.dateRange)this.setState({data:newData})}}render(){return(<svgclassName="Chart"/>)}} 功能组成 实际上,最后一个示例仍在类组件中。我们存储data是state为了防止每次组件更新时重新计算它。 但是我们不再需要使用state!而是使用useMemo(),仅data当其依赖项数组更改时才会重新计算。 constChart=({dateRange})=>{constdata=useMemo(()=>(getDataWithinRange(dateRange)),[dateRange])return(<svgclassName="Chart"/>)} ❝ 注意,我们可以只在函数内部定义变量。 ❞ constChart=({dateRange})=>{constnewData=getDataWithinRange(dateRange)return(<svgclassName="Chart"/>)} 除非我们的getDataWithinRange()函数在计算上消耗很大,否则这就是非常完美。我平时使用useMemo用的非常多,特别是在处理大型数据集时,以保持性能。 考虑使用context 想象一下,我们有许多需要计算的值,但是它们取决于不同的props。例如,我们需要计算: 我们 data在我们的 dateRange变化 的 dimensions图表的时 margins变化 我们 scales在我们的 data变化 类组成 classChartextendsComponent{state={data:null,dimensions:null,xScale:null,yScale:null,}componentDidMount(){constnewData=getDataWithinRange(this.props.dateRange)this.setState({data:newData})this.setState({dimensions:getDimensions()})this.setState({xScale:getXScale()})this.setState({yScale:getYScale()})}componentDidUpdate(prevProps,prevState){if(prevProps.dateRange!=this.props.dateRange){constnewData=getDataWithinRange(this.props.dateRange)this.setState({data:newData})}if(prevProps.margins!=this.props.margins){this.setState({dimensions:getDimensions()})}if(prevState.data!=this.state.data){this.setState({xScale:getXScale()})this.setState({yScale:getYScale()})}}render(){return(<svgclassName="Chart"/>)}} 功能组成 在我们的功能组件中,我们只需要简单的几句: constChart=({dateRange,margins})=>{constdata=useMemo(()=>(getDataWithinRange(dateRange)),[dateRange])constdimensions=useMemo(getDimensions,[margins])constxScale=useMemo(getXScale,[data])constyScale=useMemo(getYScale,[data])return(<svgclassName="Chart"/>)} 在我们的示例中,我们的类组件为什么会笨拙? 这是因为我们有很多的声明代码来去同步变量props和state,但在功能组件,我们只注重什么保持同步。 平时尽可能使用useMemo()钩子-让我们来实现功能效果。 现在再来一个需求 好的!继续前进-如果我们scales需要根据dimensions图表的图表进行更改怎么办? 类组成 在我们的类组件中,我们需要比较我们prevState和current state classChartextendsComponent{state={data:null,dimensions:null,xScale:null,yScale:null,}componentDidMount(){constnewData=getDataWithinRange(this.props.dateRange)this.setState({data:newData})this.setState({dimensions:getDimensions()})this.setState({xScale:getXScale()})this.setState({yScale:getYScale()})}componentDidUpdate(prevProps,prevState){if(prevProps.dateRange!=this.props.dateRange){constnewData=getDataWithinRange(this.props.dateRange)this.setState({data:newData})}if(prevProps.margins!=this.props.margins){this.setState({dimensions:getDimensions()})}if(prevState.data!=this.state.data||prevState.dimensions!=this.state.dimensions){this.setState({xScale:getXScale()})this.setState({yScale:getYScale()})}}render(){return(<svgclassName="Chart"/>)}} 功能组成 constChart=({dateRange,margins})=>{constdata=useMemo(()=>(getDataWithinRange(dateRange)),[dateRange])constdimensions=useMemo(getDimensions,[margins])constxScale=useMemo(getXScale,[data,dimensions])constyScale=useMemo(getYScale,[data,dimensions])return(<svgclassName="Chart"/>)} 是不是爽歪歪! 保持代码简洁 较短的代码不一定更易于阅读,但是使我们的组件尽可能地整洁无疑是一个优势! 最后 关注我们添加【前端进阶技术群】,回复:【资料包】领取前端进阶资料包 在看、转发支持作者❤️ 本文分享自微信公众号 - 前端人(FrontendPeople)。如有侵权,请联系 support@oschina.cn 删除。本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

优秀的个人博客,低调大师

Frida hook带handler的method

有些Class里面有Handler对象,就必须在 主线程里执行,否则报错 E/AndroidRuntime( 2434): java.lang.ExceptionInInitializerError E/AndroidRuntime( 2434): at dalvik.system.NativeStart.run(Native Method) E/AndroidRuntime( 2434): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() E/AndroidRuntime( 2434): at android.os.Handler.(Handler.java:200) Frida提供了这样的设施, 那就是 scheduleOnMainThread send(Java.available); Java.perform(function () { send(Java.androidVersion); send(Java.isMainThread()); Java.scheduleOnMainThread(function () { send(Java.isMainThread()); var Mgr = Java.use("me.app.im.Mgr"); var MgrInstance = Mgr.a(); var Region = MgrInstance.v(); send(Region); }); });

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

用户登录
用户注册