五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

基于Cssom的暗鏈檢測技術(shù)

2023-06-14 09:44 作者:chaojilaji123  | 我要投稿

原文合集地址如下,有需要的朋友可以關(guān)注


[本文地址](https://mp.weixin.qq.com/s/2n2QPkuChzTCezseMHIwMQ)


[合集地址](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzI5MjY4OTQ2Nw==&action=getalbum&album_id=2968591493596708865&scene=173&from_msgid=2247484203&from_itemidx=1&count=3&nolastread=1#wechat_redirect)


# 什么是暗鏈

大部分的開源代碼在實現(xiàn)暗鏈檢測的時候都是直接判斷頁面里面有沒有敏感詞,如果有,就認為該鏈接為暗鏈。這種做法其實是有誤的。

違規(guī)鏈接應該分為:外鏈、內(nèi)鏈、死鏈和暗鏈。而暗鏈除了違規(guī),還應該具備“暗”這個看不見的特征。


## 暗鏈的特征

其實“暗鏈”就是看不見的網(wǎng)站鏈接,“暗鏈”在網(wǎng)站中的鏈接做得非常隱蔽,短時間內(nèi)不易被搜索引擎察覺。是做非法SEO的常用手段。



下面是一些特征

```html


<!-- 正常連接 -->

<a href="https://www.baidu.com">正常外鏈</a>


<!-- position位置類暗鏈 -->

<!-- position位置樣式,將元素的top、left位置設(shè)置成負數(shù),讓元素處于可視區(qū)外 -->

<a href="https://www.h0ksd3.6dayxpj.com:8989" style="position: absolute; top: -999px; left: -999px;">position暗鏈</a>


<!-- display 和 visibility 隱藏類暗鏈 -->

<a href="https://www.h0ksd3.6dayxpj.com:8989" style="display: none;">display為none使得鏈接不可見</a>

<a href="https://www.h0ksd3.6dayxpj.com:8989" style="visibility: hidden;">display為hidden使得鏈接不可見</a>


<!-- 鏈接顏色和文字類暗鏈 -->

<!-- 鏈接顏色與背景色相同或相似,color采用十六進制表達色彩 -->

<a href="https://www.h0ksd3.6dayxpj.com:8989" style="color: #ffffff;">鏈接顏色與背景色相同或相似,采用十六進制表達色彩</a>

<!-- 鏈接顏色與背景色相同或相似,color采用顏色英文名稱表達色彩 -->

<a href="https://www.h0ksd3.6dayxpj.com:8989" style="color: white;">鏈接顏色與背景色相同或相似,采用顏色英文名稱表達色彩</a>

<!-- 鏈接顏色透明,color采用transparent值 -->

<a href="https://www.h0ksd3.6dayxpj.com:8989" style="color: transparent">鏈接顏色透明</a>

<!-- 鏈接文字設(shè)置為0,使得不可見 -->

<a href="https://www.h0ksd3.6dayxpj.com:8989" style="font-size: 0px;">鏈接文字字號為0像素</a>


<!-- marquee類暗鏈 -->

<!-- 將marquee的scrollamount屬性值調(diào)為較大值,使跑馬燈移動速度超過人眼可見范圍,達到隱藏效果 -->

<marquee scrollamount="100000"><a href="https://www.h0ksd3.6dayxpj.com:8989">我的車速夠快,你也看不見我</a></marquee>

<!-- 將marquee的scrolldelay屬性值調(diào)為較大值,使跑馬燈移動速度非常慢,很長時間都不會在屏幕中出現(xiàn)該鏈接,達到隱藏效果 -->

<marquee scrolldelay="100000"><a href="https://www.h0ksd3.6dayxpj.com:8989">我發(fā)車夠慢,你也不容易發(fā)現(xiàn)我</a></marquee>


<!-- JS寫入CSS樣式類暗鏈 -->

<!-- 利用JavaScript的document.write方法寫入一個CSS樣式屬性display為none,或者visibility為hidden的層來包裹需要隱藏的鏈接,達到隱藏暗鏈的效果 -->

<script language="javascript" type="text/javascript">

? ? document.write("<div style=\'display:none;\'>");

</script>

<a href=https://www.h0ksd3.6dayxpj.com:8989>通過JavaScript寫入包裹該鏈接的隱藏層,使得鏈接不可見</a>

<script language="javascript" type="text/javascript">

? ? document.write("</div>");?

</script>


<!-- JS修改CSS樣式類暗鏈 -->

<!-- 利用JavaScript修改CSS樣式屬性display為none,或者visibility為hidden來達到隱藏的效果 -->

<a href="https://www.h0ksd3.6dayxpj.com:8989" id="link1">通過JavaScript修改了本鏈接可見屬性設(shè)置為隱藏,使得鏈接不可見</a>

<script language="javascript" type="text/javascript">

? ? document.getElementById("link1").style.display = "none";

</script>


<!-- z-index類暗鏈 -->

<!-- 用z-index屬性堆疊遮擋,z-index值越小堆疊越靠后 -->

<div id="container" style="position: relative;">

? ? <div id="box1"

? ? ? ? style="position: absolute; top: 0; left: 0; width: 90%; height: 100px; background-color: yellow; z-index: 999;">

? ? ? ? 我是一個div層,這一層下面隱藏著鏈接

? ? </div>

? ? <div id="box2">

? ? ? ? <a href="https://www.h0ksd3.6dayxpj.com:8989">被z-index較大的div層把我遮擋了,你也看不見我</a>

? ? </div>

</div>


<!-- iframe內(nèi)聯(lián)框架類暗鏈 -->

<!-- 利用 iframe 創(chuàng)建隱藏的內(nèi)聯(lián)框架,frameborder設(shè)置邊框?qū)挾葹?,width寬度或height高度設(shè)置為0時,就不可見 -->

<iframe src="https://httpbin.org/get" frameborder="10px" width="0px"

? ? height="0px">我是一個iframe內(nèi)鏈框架,frameborder為0,寬度為0時或高度為0時,你就看不見我了</iframe>


<!-- 重定向方式暗鏈 -->

<!-- 采用setTimeout,在跳轉(zhuǎn)到正常網(wǎng)站頁面前植入暗鏈,等待很短時間就跳轉(zhuǎn)到正常頁面,用戶不易察覺 -->

<script>setTimeout('window.location="index.html"', 0.1)</script>

<body leftmargin="0" topmargin="0" scroll="no">

? ? <a href="https://h0ksd3.6dayxpj.com:8989">新葡京娛樂城</a>

</body>

<!-- 采用meta標簽,通過設(shè)置http-equiv為refresh,結(jié)合content中攜帶需跳轉(zhuǎn)的鏈接和較短等待時間,來實現(xiàn)重定向,不過該種方式很容易被用戶發(fā)現(xiàn)異常 -->

<head>

? ? <meta http-equiv="refresh" content="1;url=https://h0ksd3.6dayxpj.com:8989" />

</head>


<!-- meta標簽類暗鏈 -->

<!-- 設(shè)置meta的name屬性值為keywords,content為包含暗鏈的文字,或通過十進制或十六進制的HTML編碼或HTML實體編碼方式逃避靜態(tài)爬蟲爬取后不做解碼處理的方式 -->

<head>

? ? <!-- 用于搜索引擎SEO -->

? ? <meta name="keywords" content="澳門新普京最新官方網(wǎng)站【abcd.com】" />

? ? <!-- 采用十進制的HTML編碼 -->

? ? <meta name="keywords"

? ? ? ? content="&#28595;&#38376;&#26032;&#26222;&#20140;&#26368;&#26032;&#23448;&#26041;&#32593;&#31449;&#12304;&#97;&#98;&#99;&#100;&#46;&#99;&#111;&#109;&#12305;" />

? ? <!-- 采用十六進制的HTML編碼 -->

? ? <meta name="keywords"

? ? ? ? content="&#x6fb3;&#x95e8;&#x65b0;&#x666e;&#x4eac;&#x6700;&#x65b0;&#x5b98;&#x65b9;&#x7f51;&#x7ad9;&#x3010;&#x61;&#x62;&#x63;&#x64;&#x2e;&#x63;&#x6f;&#x6d;&#x3011;" />

? ? <!-- 采用HTML實體編碼 -->

? ? <meta name="keywords" content="澳門新普京最新官方網(wǎng)站【abcd&period;com】" />

</head>

```

我們可以根據(jù)此構(gòu)造出一個具有暗鏈的網(wǎng)站,然后利用代碼去檢測

# 什么是CSSOM

來看看chatgpt怎么說

>CSSOM(CSS Object Model)是指CSS對象模型,它是一種表示和操作CSS樣式信息的API(應用程序接口)。類似于DOM(文檔對象模型)用于操作HTML文檔的結(jié)構(gòu)和內(nèi)容,CSSOM用于操作和控制CSS樣式的規(guī)則、屬性和值。

CSSOM提供了一組接口和方法,允許開發(fā)人員通過JavaScript訪問和修改CSS樣式信息。它可以用于動態(tài)地創(chuàng)建、修改或刪除CSS規(guī)則,以及獲取和修改元素的CSS屬性和值。

通過CSSOM,開發(fā)人員可以實現(xiàn)一些常見的樣式操作,例如:

動態(tài)地改變元素的樣式,比如修改背景顏色、字體大小等。

動態(tài)地添加、刪除或修改CSS規(guī)則,從而改變整個文檔的樣式。

訪問和獲取元素的計算樣式(computed style),即應用在元素上的最終樣式值。

操作CSS動畫和過渡效果,包括啟動、停止或修改動畫。

CSSOM的主要優(yōu)勢之一是可以與DOM無縫集成,通過將CSS樣式與HTML文檔結(jié)構(gòu)和內(nèi)容分開,可以實現(xiàn)更好的可維護性和靈活性。它在前端開發(fā)中扮演著重要的角色,讓開發(fā)人員能夠以編程的方式操控和控制頁面的樣式外觀和交互效果。


我們通過playwright爬蟲,通過執(zhí)行js函數(shù),將所有暗鏈檢測中可能使用到的css屬性全部獲取到,具體的方法為:

```javascript

function traverseDOMTree(node) {

? ? ? ? ? ? ? ? ? // 檢查節(jié)點是否為元素節(jié)點

? ? ? ? ? ? ? ? ? cssom = []

? ? ? ? ? ? ? ? ? if (node.nodeType === Node.ELEMENT_NODE) {

? ? ? ? ? ? ? ? ? ? // 輸出節(jié)點的 class 屬性


? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? const e = node;

? ? ? ? ? ? ? ? ? const styles = window.getComputedStyle(e);

? ? ? ? ? ? ? ? ? const ans = {

? ? ? ? ? ? ? ? ? ? ? ? 'tag_name':e.tagName,

? ? ? ? ? ? ? ? ? ? ? ? 'attribute_content':e.hasAttribute('content') ? e.attributes['content'].value : '',

? ? ? ? ? ? ? ? ? ? ? ? 'background_color':styles['background-color'],

? ? ? ? ? ? ? ? ? ? ? ? 'color':styles['color'],

? ? ? ? ? ? ? ? ? ? ? ? 'display':styles['display'],

? ? ? ? ? ? ? ? ? ? ? ? 'font_size':styles['font-size'],

? ? ? ? ? ? ? ? ? ? ? ? 'frameborder':e.hasAttribute('frameborder') ? e.attributes['frameborder'].value : '',

? ? ? ? ? ? ? ? ? ? ? ? 'height':styles['height'],

? ? ? ? ? ? ? ? ? ? ? ? 'href':e.href,

? ? ? ? ? ? ? ? ? ? ? ? 'http_equiv':e.hasAttribute('http-equiv') ? e.attributes['http-equiv'].value : '',

? ? ? ? ? ? ? ? ? ? ? ? 'language':e.hasAttribute('language') ? e.attributes['language'].value : '',

? ? ? ? ? ? ? ? ? ? ? ? 'left':styles['left'],

? ? ? ? ? ? ? ? ? ? ? ? 'position':styles['position'],

? ? ? ? ? ? ? ? ? ? ? ? 'scroll_delay':e.hasAttribute('scrolldelay') ? e.attributes['scrolldelay'].value : '',

? ? ? ? ? ? ? ? ? ? ? ? 'src':e.hasAttribute('src') ? e.attributes['src'].value : '',

? ? ? ? ? ? ? ? ? ? ? ? 'scroll_amount':e.hasAttribute('scrollamount') ? e.attributes['scrollamount'].value : '',

? ? ? ? ? ? ? ? ? ? ? ? 'top':styles['top'],

? ? ? ? ? ? ? ? ? ? ? ? 'width':styles['width'],

? ? ? ? ? ? ? ? ? ? ? ? 'visibility':styles['visibility'],

? ? ? ? ? ? ? ? ? ? ? ? 'z_index':styles['z-index'],

? ? ? ? ? ? ? ? ? ? ? ? 'children':[]

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? // 遍歷所有子節(jié)點

? ? ? ? ? ? ? ? ? for (let i = 0; i < node.childNodes.length; i++) {

? ? ? ? ? ? ? ? ? ? const childNode = node.childNodes[i];


? ? ? ? ? ? ? ? ? ? // 遞歸遍歷子節(jié)點

? ? ? ? ? ? ? ? ? ? if (childNode.nodeType === Node.ELEMENT_NODE) {

? ? ? ? ? ? ? ? ? ? ? const x = traverseDOMTree(childNode);

? ? ? ? ? ? ? ? ? ? ? ans['children'].push(x)

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? return ans;

}

```

然后我們利用playwright去執(zhí)行這一段js代碼即可

```python

cssom_json = await page.evaluate(js_init_script.TraverseDOMTree.eval_traver_se_dom_tree_script())

```

獲取到的結(jié)構(gòu)為:

```json

"cssom_view": {

"tag_name": "HTML",

"attribute_content": "",

"background_color": "rgba(0, 0, 0, 0)",

"color": "rgb(0, 0, 0)",

"display": "block",

"font_size": "16px",

"frameborder": "",

"height": "251.312px",

"href": null,

"http_equiv": "",

"language": "",

"left": "auto",

"position": "static",

"scroll_delay": "",

"src": "",

"scroll_amount": "",

"top": "auto",

"width": "1280px",

"visibility": "visible",

"z_index": "auto",

"children": []

```

children里面也是這樣的結(jié)構(gòu)。

# 檢測過程

## 編寫檢測配置文件

首先,由于暗鏈的放置方法是無窮的,上面的例子只是其中一小部分,所以考慮使用poc的方式來動態(tài)配置檢測的規(guī)則

下面是根據(jù)上面的特征,編寫的一些poc文件

### z-index類堆疊暗鏈

```yml

nodes:

? - node_name: 'father-brother'

? ? css_rules:

? ? ? - css_name: 'z_index'

? ? ? ? value: '>100'

rule_name: 'z-index類暗鏈'

description: '用z-index屬性堆疊遮擋,z-index值越小堆疊越靠后'

```

### 顏色

```yml

nodes:

? - node_name: 'own'

? ? css_rules:

? ? ? - css_name: 'color'

? ? ? ? value: '=#ffffff'

rule_name: '鏈接顏色和文字類暗鏈'

description: '鏈接顏色與背景色相同或相似,color采用十六進制表達色彩'

```


```yml

nodes:

? - node_name: 'own'

? ? css_rules:

? ? ? - css_name: 'color'

? ? ? ? value: '=transparent'

rule_name: '鏈接顏色和文字類暗鏈'

description: '鏈接顏色透明,color采用transparent值'

```


```yml

nodes:

? - node_name: 'own'

? ? css_rules:

? ? ? - css_name: 'color'

? ? ? ? value: '=white'

rule_name: '鏈接顏色和文字類暗鏈'

description: '鏈接顏色與背景色相同或相似,color采用顏色英文名稱表達色彩'

```

### 字體大小

```yml

nodes:

? - node_name: 'own'

? ? css_rules:

? ? ? - css_name: 'font_size'

? ? ? ? value: '=0'

rule_name: '鏈接顏色和文字類暗鏈'

description: '鏈接文字設(shè)置為0,使得不可見'

```


### 跑馬燈

```yml

nodes:

? - node_name: 'father'

? ? tag_rules:

? ? ? - tag_name: 'marquee'

? ? ? ? attribute_name: 'scrolldelay'

? ? ? ? attribute_value: '>100'

rule_name: 'marquee類暗鏈'

description: '將marquee的scrolldelay屬性值調(diào)為較大值,使跑馬燈移動速度非常慢,很長時間都不會在屏幕中出現(xiàn)該鏈接,達到隱藏效果'

```


```yml

nodes:

? - node_name: 'father'

? ? tag_rules:

? ? ? - tag_name: 'marquee'

? ? ? ? attribute_name: 'scrollamount'

? ? ? ? attribute_value: '>100'

rule_name: 'marquee類暗鏈'

description: '將marquee的scrollamount屬性值調(diào)為較大值,使跑馬燈移動速度超過人眼可見范圍,達到隱藏效果'

```


### 可見性

```yml

nodes:

? - node_name: 'own'

? ? css_rules:

? ? ? - css_name: 'position'

? ? ? ? value: '=absolute'

? ? ? - css_name: 'top'

? ? ? ? value: '<0'

? ? ? - css_name: 'left'

? ? ? ? value: '<0'

rule_name: 'position位置類暗鏈'

description: 'position位置樣式,將元素的top、left位置設(shè)置成負數(shù),讓元素處于可視區(qū)外'

```


```yml

nodes:

? - node_name: 'own'

? ? css_rules:

? ? ? - css_name: 'visibility'

? ? ? ? value: '=hidden'

rule_name: 'visibility 隱藏類暗鏈'

description: ''

```

## 解析檢測配置文件,并進行檢測

### 定義規(guī)則文件的結(jié)構(gòu)

```java

public class DarkCheckRule {

? ? private String ruleName;

? ? private String description;

? ? private List<DarkCheckRuleNode> nodes;

}


public class DarkCheckRuleNode {

? ? private String nodeName;

? ? private List<DarkCheckNodeCssRule> cssRules;

? ? private List<DarkCheckNodeTag> tagRules;

}


public class DarkCheckNodeCssRule {

? ? private String cssName;

? ? private String value;

}


public class DarkCheckNodeTag {

? ? private String tagName;

? ? private String attributeName;

? ? private String attributeValue;

}

```

規(guī)則分為兩種,第一是檢測最終css屬性,第二是檢測標簽、屬性和值。

### 將yml內(nèi)容反序列化成規(guī)則對象

```java

// 讀取文件內(nèi)容

?public static String getFileContent(String fileName, Boolean absolutePath) {

? ? ? ? if (absolutePath) {

? ? ? ? ? ? try {

? ? ? ? ? ? ? ? return getFileContent(new File(new File(".").getCanonicalPath() + "/" + fileName));

? ? ? ? ? ? } catch (IOException e) {

? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? }

? ? ? ? ? ? return "";

? ? ? ? } else {

? ? ? ? ? ? try {

? ? ? ? ? ? ? ? return getFileContent(new File(fileName));

? ? ? ? ? ? }catch (Exception e){

? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? }

? ? ? ? ? ? return "";

? ? ? ? }

? ? }


public static Map<String, Object> toMap(String yamlString) {

? ? ? ? Yaml yaml = new Yaml();

? ? ? ? return yaml.load(yamlString);

? ? }


public static Map<String, Object> loadFromFile2Map(String fileName) {

? ? ? ? return toMap(FileUtils.getFileContent(fileName, false));

? ? }


/**

? ? ?* 對象轉(zhuǎn)換成Json

? ? ?*

? ? ?* @param object Object

? ? ?* @return String

? ? ?*/

? ? public static String toJson(Object object) {

? ? ? ? StringWriter sw = new StringWriter();

? ? ? ? if (Objects.isNull(object)) {

? ? ? ? ? ? return EMPTY_JSON_OBJECT;

? ? ? ? }

? ? ? ? try {

? ? ? ? ? ? MAPPER.writeValue(MAPPER.getFactory().createGenerator(sw), object);

? ? ? ? } catch (Exception ex) {

? ? ? ? ? ? LOGGER.error("Object to json occur error, detail:", ex);

? ? ? ? }

? ? ? ? return sw.toString();

? ? }


public static <T> T toObject(String jsonString, Class<T> tClass) {

? ? ? ? if (Objects.isNull(jsonString) || jsonString.trim().isEmpty()) {

? ? ? ? ? ? return null;

? ? ? ? }

? ? ? ? try {

? ? ? ? ? ? return MAPPER.readValue(jsonString, tClass);

? ? ? ? } catch (Exception ex) {

? ? ? ? ? ? ex.printStackTrace();

//? ? ? ? ? ? LOGGER.error("Json to object occur error, detail:", ex);

? ? ? ? }

? ? ? ? return null;

? ? }

```

然后調(diào)用上述工具類

```java

?DarkCheckRule darkCheckRule = Json.toObject(Json.toJson(YamlUtils.loadFromFile2Map(dir1.getAbsolutePath())), DarkCheckRule.class);

```

### 檢測過程

首先,暗鏈肯定是鏈接,所以首先應該遍歷這個cssom的json,然后找到A標簽等于目標鏈接的,再對該標簽進行特征檢測

```java

if (cssomView.getTagName().equalsIgnoreCase("A")) {

? ? ? ? ? ? if (cssomView.getHref().equalsIgnoreCase(targetUrl)

? ? ? ? ? ? ? ? ? ? || cssomView.getSrc().equalsIgnoreCase(targetUrl)) {

? ? ? ? ? ? ? ? // TODO: 2023/5/10 開始檢測

? ? ? ? ? ? ? ? for (DarkCheckRule darkCheckRule : darkCheckRules) {

? ? ? ? ? ? ? ? ? ? if (Boolean.TRUE.equals(check(darkCheckRule, cssomView))) {

? ? ? ? ? ? ? ? ? ? ? ? // TODO: 2023/5/10 說明有匹配的

? ? ? ? ? ? ? ? ? ? ? ? checkAns.add(darkCheckRule.getRuleName() + "-" + darkCheckRule.getDescription());

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? return;

? ? ? ? }

```

下面是檢測某一個規(guī)則的方法

```java

public Boolean check(DarkCheckRule darkCheckRule, NewCssomView cssomView) {

? ? ? ? // TODO: 2023/5/10

? ? ? ? List<DarkCheckRuleNode> darkCheckRuleNodes = darkCheckRule.getNodes();

? ? ? ? int flag = 0;

? ? ? ? for (DarkCheckRuleNode darkCheckRuleNode : darkCheckRuleNodes) {

? ? ? ? ? ? if (Boolean.FALSE.equals(checkOneNode(darkCheckRuleNode, cssomView))) {

? ? ? ? ? ? ? ? // TODO: 2023/5/10 需要都滿足才行

? ? ? ? ? ? ? ? flag = 1;

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? if (flag == 0) {

? ? ? ? ? ? return true;

? ? ? ? }

? ? ? ? return false;

? ? }


/**

? ? ?* 檢測規(guī)則中的某一個規(guī)則節(jié)點

? ? ?*

? ? ?* @param darkCheckRuleNode

? ? ?* @param cssomView

? ? ?* @return

? ? ?*/

? ? public Boolean checkOneNode(DarkCheckRuleNode darkCheckRuleNode, NewCssomView cssomView) {

? ? ? ? List<DarkCheckNodeCssRule> darkCheckNodeCssRules = darkCheckRuleNode.getCssRules();

? ? ? ? if (darkCheckRuleNode.getNodeName().equalsIgnoreCase("own")) {

? ? ? ? ? ? // TODO: 2023/5/10 檢測自己

? ? ? ? ? ? return getOneNodeResult(darkCheckRuleNode, cssomView);

? ? ? ? } else if (darkCheckRuleNode.getNodeName().equalsIgnoreCase("children")) {

? ? ? ? ? ? // TODO: 2023/5/15 獲取所有本層子節(jié)點,不考慮遞歸,只要有一個滿足即可

? ? ? ? ? ? for (NewCssomView newCssomView : cssomView.getChildren()) {

? ? ? ? ? ? ? ? if (Boolean.TRUE.equals(getOneNodeResult(darkCheckRuleNode, newCssomView))) {

? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? return false;

? ? ? ? } else if (darkCheckRuleNode.getNodeName().equalsIgnoreCase("father")) {

? ? ? ? ? ? // TODO: 2023/5/10 檢測父級,只要有一個父級滿足即可

? ? ? ? ? ? while (true) {

? ? ? ? ? ? ? ? if (Objects.isNull(cssomView.getFather())) break;

? ? ? ? ? ? ? ? if (Boolean.TRUE.equals(getOneNodeResult(darkCheckRuleNode, cssomView.getFather()))) {

? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? }

//? ? ? ? ? ? ? ? System.out.println("1");

? ? ? ? ? ? ? ? return checkOneNode(darkCheckRuleNode, cssomView.getFather());

? ? ? ? ? ? }

? ? ? ? ? ? return false;

? ? ? ? } else if (darkCheckRuleNode.getNodeName().equalsIgnoreCase("brother")) {

? ? ? ? ? ? // TODO: 2023/5/10 檢測同級節(jié)點

? ? ? ? ? ? // TODO: 2023/5/15 親兄弟

? ? ? ? ? ? for (NewCssomView newCssomView : cssomView.getFather().getChildren()) {

? ? ? ? ? ? ? ? if (Boolean.TRUE.equals(getOneNodeResult(darkCheckRuleNode,newCssomView))){

? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? return false;

? ? ? ? } else if (darkCheckRuleNode.getNodeName().equalsIgnoreCase("father-brother")) {

? ? ? ? ? ? // TODO: 2023/5/15 父級的親兄弟

? ? ? ? ? ? while (true){

? ? ? ? ? ? ? ? if (Objects.isNull(cssomView.getFather()))break;

? ? ? ? ? ? ? ? for (NewCssomView newCssomView : cssomView.getFather().getChildren()){

? ? ? ? ? ? ? ? ? ? if (Boolean.TRUE.equals(getOneNodeResult(darkCheckRuleNode,newCssomView))){

? ? ? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? return checkOneNode(darkCheckRuleNode,cssomView.getFather());

? ? ? ? ? ? }

? ? ? ? ? ? return false;

? ? ? ? }

? ? ? ? return false;

? ? }


public Boolean getOneNodeResult(DarkCheckRuleNode darkCheckRuleNode, NewCssomView cssomView) {

? ? ? ? int flag = 0;

? ? ? ? // TODO: 2023/5/15檢測完所有的CCSRULE

? ? ? ? if (Objects.nonNull(darkCheckRuleNode.getCssRules())){

? ? ? ? ? ? for (DarkCheckNodeCssRule darkCheckNodeCssRule : darkCheckRuleNode.getCssRules()) {

? ? ? ? ? ? ? ? if (Boolean.FALSE.equals(checkOneCssRule(darkCheckNodeCssRule, cssomView))) {

? ? ? ? ? ? ? ? ? ? flag = 1;

? ? ? ? ? ? ? ? ? ? break;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? if (Objects.nonNull(darkCheckRuleNode.getTagRules())){

? ? ? ? ? ? for (DarkCheckNodeTag darkCheckNodeTag : darkCheckRuleNode.getTagRules()) {


? ? ? ? ? ? ? ? if (Boolean.FALSE.equals(checkOneTagRule(darkCheckNodeTag, cssomView))) {

? ? ? ? ? ? ? ? ? ? flag = 1;

? ? ? ? ? ? ? ? ? ? break;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }


? ? ? ? if (flag == 0) {

? ? ? ? ? ? // TODO: 2023/5/10 都成功

? ? ? ? ? ? return true;

? ? ? ? }

? ? ? ? return false;

? ? }


/**

? ? ?* 檢測某一個css的結(jié)果

? ? ?*

? ? ?* @param darkCheckNodeCssRule

? ? ?* @param cssomView

? ? ?* @return

? ? ?*/

? ? public Boolean checkOneCssRule(DarkCheckNodeCssRule darkCheckNodeCssRule, NewCssomView cssomView) {

? ? ? ? NewCssomView father = cssomView.getFather();

? ? ? ? cssomView.setFather(null);

? ? ? ? Map<String, Object> x = Json.toMap(Json.toJson(cssomView));

? ? ? ? cssomView.setFather(father);

? ? ? ? try {

? ? ? ? ? ? if (Objects.nonNull(x.get(darkCheckNodeCssRule.getCssName()))) {

? ? ? ? ? ? ? ? String value = darkCheckNodeCssRule.getValue();

? ? ? ? ? ? ? ? String aaa = (String) x.getOrDefault(darkCheckNodeCssRule.getCssName(), "0");

? ? ? ? ? ? ? ? if (value.startsWith("<")) {

? ? ? ? ? ? ? ? ? ? Integer xxx = MathUtils.toInt(aaa);

? ? ? ? ? ? ? ? ? ? if (xxx < MathUtils.toInt(value)) {

? ? ? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (value.startsWith(">")) {

? ? ? ? ? ? ? ? ? ? Integer xxx = MathUtils.toInt(aaa);


? ? ? ? ? ? ? ? ? ? if (xxx > MathUtils.toInt(value)) {

? ? ? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (value.startsWith("=")) {

? ? ? ? ? ? ? ? ? ? try {

? ? ? ? ? ? ? ? ? ? ? ? if (aaa.toLowerCase().contains(value.substring(1).toLowerCase())) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? } catch (Exception e) {

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (value.equalsIgnoreCase("=")) {

? ? ? ? ? ? ? ? ? ? Integer xxx = MathUtils.toInt(aaa);

? ? ? ? ? ? ? ? ? ? if (xxx == MathUtils.toInt(value)) {

? ? ? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? } catch (Exception e) {

? ? ? ? }

? ? ? ? return false;

? ? }


public Boolean checkOneTagRule(DarkCheckNodeTag darkCheckNodeTag, NewCssomView cssomView) {

? ? ? ? NewCssomView father = cssomView.getFather();

? ? ? ? cssomView.setFather(null);

? ? ? ? Map<String, Object> x = Json.toMap(Json.toJson(cssomView));

? ? ? ? cssomView.setFather(father);

? ? ? ? try {

? ? ? ? ? ? if (Objects.nonNull(x.get("tag_name"))) {

? ? ? ? ? ? ? ? String tagName = x.getOrDefault("tag_name", "").toString();

? ? ? ? ? ? ? ? Integer trueNumber = 0;

? ? ? ? ? ? ? ? String conditionValue = darkCheckNodeTag.getAttributeValue();

? ? ? ? ? ? ? ? if (tagName.equalsIgnoreCase(darkCheckNodeTag.getTagName())) {

? ? ? ? ? ? ? ? ? ? String conditionName = darkCheckNodeTag.getAttributeName();

? ? ? ? ? ? ? ? ? ? if (conditionName.equalsIgnoreCase("scrollamount")) {

? ? ? ? ? ? ? ? ? ? ? ? String trueValue = cssomView.getScrollAmount();

? ? ? ? ? ? ? ? ? ? ? ? trueNumber = MathUtils.toInt(trueValue);

? ? ? ? ? ? ? ? ? ? } else if (conditionName.equalsIgnoreCase("scrolldelay")) {

? ? ? ? ? ? ? ? ? ? ? ? trueNumber = MathUtils.toInt(cssomView.getScrollDelay());

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? Integer conditionNumber = MathUtils.toInt(conditionValue);

? ? ? ? ? ? ? ? if (conditionValue.startsWith(">")) {

? ? ? ? ? ? ? ? ? ? if (trueNumber > conditionNumber) {

? ? ? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (conditionValue.startsWith("<")) {

? ? ? ? ? ? ? ? ? ? if (trueNumber < conditionNumber) {

? ? ? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (conditionValue.startsWith("=")) {

? ? ? ? ? ? ? ? ? ? if (trueNumber == conditionNumber) {

? ? ? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? } catch (Exception e) {

? ? ? ? }

? ? ? ? return false;


? ? }

```

接下來要做的就是進一步完善檢測poc即可


基于Cssom的暗鏈檢測技術(shù)的評論 (共 條)

分享到微博請遵守國家法律
翁牛特旗| 北票市| 翼城县| 香港 | 于都县| 大石桥市| 安多县| 黑水县| 三明市| 兴山县| 炉霍县| 松桃| 宁蒗| 陆川县| 平顶山市| 濮阳市| 余姚市| 兴国县| 琼海市| 松滋市| 婺源县| 南乐县| 前郭尔| 图木舒克市| 宁晋县| 疏勒县| 南澳县| 镇宁| 文安县| 大冶市| 枣阳市| 格尔木市| 万载县| 瑞丽市| 建平县| 深泽县| 原平市| 闽侯县| 枞阳县| 昌黎县| 谢通门县|