前几天偶然看到前面写的头条js获取的参数已经无法通过验证了。 看了新的js,经过三天半的调试,终于找到了原因。
1> 全局搜索找到_signature生成的函数。
2> 输入函数。
这里可以看到传入的参数和之前不一样了,现在传入的是一个url对象,里面的as和cp参数的生成就跳过了,比较简单。
3> 输入这个g.sign函数调用
里面是一个匿名函数的技巧。 在这个匿名函数处打断点,点击页面刷新,进入这个匿名函数执行的地方,根据调用堆栈找到这个地方。
这里,调用这个匿名函数时,传入一串字符,经过短暂的操作,就为g.sign定义了函数调用方法。 观察这一串字符串,与之前相比,应该已经发生了很大的变化。
接下来我们构造调用方法,命名匿名函数javascript匿名函数,并传入一个字符串和一个对象。 然后调用这个对象的sign方法传入参数获取_signature,是的,和之前没有任何变化。 当我们构建导航器并运行它时,我们可以看到参数 gg。
显然这上面还有其他的坑。
建议您将片段调试与本地调试结合使用。
然后我们看一下代码,下一步需要很大的耐心,切记。
这段代码已经被混淆了javascript匿名函数,尤其是switch和case调用的形式,根本无法根据调用栈找到规则。 笔者选择的是硬杠。
复制关键参数。
是的,调试这些东西花了三天时间。 可以看到canvas的2D绘制和文档操作已经完成,ua已经验证完毕。 该怎么办。
一一模拟。
本地测试。 。 。 。 还是gg啊
现在我想到2种可能:
1、模拟不彻底。
2、网站环境有其他验证参数。
首先考虑第二种。 这个验证非常简单。 获取Snippets并将其放在网站页面上进行测试,并比较参数。
然后考虑对cookie进行操作。 与油猴冉鸾测试。
决不。
继续调试,对比本地和网站调试的结果。
终于在一处找到了原因。
这就是原因。 全局搜索 tac。
终于在主页源码中找到了答案。 带入典以辩解。 成功。
终于:
后来我发现今日头条没有验证画布,但这并不重要。 确实,反爬的时候线越来越难受。 而且在调试过程中,我发现今日头条已经hook了网站环境中的个别功能。 想象一下,如果你在上面挖一个洞,将会杀死多少人。 另外,这种开关的调试也比较困难。
新年快乐,祝你越来越好。
有时,当我们在 C++ 应用程序中使用 IE 控件时javascript函数调用,我们需要访问 HTML 元素。 我们可以通过使用标准 COM 对象(例如 IWebBrowser2、IHTMLDocument2 等)来完成此操作。 这样我们就可以轻松实现点击按钮、点击定位、获取输入字符串、获取HTML文本等功能。 不幸的是,微软没有提供类似的JavaScript对象。 无论如何,可以通过使用传统的 COM 表单作为 HTML 页面中的 JavaScript 对象来控制它。 本文介绍了 CWebPage 类,它允许您执行从 C++ 代码调用 JavaScript 函数的技术。
由于使用了生成的类javascript函数调用,可以轻松地从 C++ 代码调用任何 JavaScript 函数。 为了实现这个功能,我们应该获取 IHTMLDocument2 套接字的指针。 如果我们使用 MFC 中的 CHtmlView 类,则可以通过使用成员函数 CHtmlView::GetHtmlDocument() 来完成此操作。 如果使用 IWebBrowser 或 IWebBrowser2 组件,函数 get_Document 将为我们提供所需的界面。 这是一个例子:
CComPtr spDisp = CHtmlView::GetHtmlDocument(); m_webPage.SetDocument(spDisp);
其余的事情将由 CWebPage 类完成。 下面是一个不带参数的 JavaScript 调用的示例。
m_webPage.CallJScript("Welcome");
带有两个参数的 JavaScript 调用示例如下所示:
m_webPage.CallJScript("Miltiply","2.34","3.32");
类的实现
class CWebPage { public: CWebPage(); virtual ~CWebPage(); bool SetDocument(IDispatch* pDisp); LPDISPATCH GetHtmlDocument() const; const CString GetLastError() const; bool GetJScript(CComPtr& spDisp); bool GetJScripts(CComPtr& spColl); CString ScanJScript(CString& strAText,CStringArray& args); bool CallJScript(const CString strFunc); bool CallJScript(const CString strFunc,const CString strArg1); bool CallJScript(const CString strFunc,const CString strArg1, const CString strArg2); bool CallJScript(const CString strFunc,const CString strArg1, const CString strArg2,const CString strArg3); bool CallJScript(const CString strFunc,const CStringArray& paramArray); protected CComPtr m_spDoc; }; 调用技术在前面提到的技术拆分以下步骤:获取一个指向IHTMLDocument2接口。
获取一个在HTML文件中的JavaScript对象的IDispatch。使用了一个JavaScript函数名字的DISPID。把参数给DISPPARAM结构。调用JavaScript的使用IDispatch接口的Invoke方法的功能。下面是一个得到一个IDispatch指针的Java脚本对象的例子:
bool CWebPage::GetJScript(CComPtr& spDisp) { HRESULT hr = m_spDoc->get_Script(&spDisp); ATLASSERT(SUCCEEDED(hr)); return SUCCEEDED(hr); }
And here is the final function to call JavaScript:
CComVariant CWebPage::CallJScript(const CString strFunc, const CStringArray& paramArray) { //Getting IDispatch for Java Script objects CComPtr spScript; if(!GetJScript(spScript)) { ShowError("Cannot GetScript"); return false; } //Find dispid for given function in the object CComBSTR bstrMember(strFunc); DISPID dispid = NULL; HRESULT hr = spScript->GetIDsOfNames(IID_NULL,&bstrMember,1, LOCALE_SYSTEM_DEFAULT,&dispid); if(FAILED(hr)) { ShowError(GetSystemErrorMessage(hr)); return false; } const int arraySize = paramArray.GetSize(); //Putting parameters DISPPARAMS dispparams; memset(&dispparams, 0, sizeof dispparams); dispparams.cArgs = arraySize; dispparams.rgvarg = new VARIANT[dispparams.cArgs]; dispparams.cNamedArgs = 0; for( int i = 0; i bstr = paramArray.GetAt(arraySize - 1 - i); // back reading bstr.CopyTo(&dispparams.rgvarg[i].bstrVal); dispparams.rgvarg[i].vt = VT_BSTR; } EXCEPINFO excepInfo; memset(&excepInfo, 0, sizeof excepInfo); CComVariant vaResult; UINT nArgErr = (UINT)-1; // initialize to invalid arg //Call JavaScript function hr = spScript->Invoke(dispid,IID_NULL,0, DISPATCH_METHOD,&dispparams, &vaResult,&excepInfo,&nArgErr); delete [] dispparams.rgvarg; if(FAILED(hr)) { ShowError(GetSystemErrorMessage(hr)); return false; } return vaResult; }
http://www.codeguru.com/Cpp/I-N/ieprogram/article.php/c4399