首页
社区
课程
招聘
[原创]Libc-Database 本地搭建实战
发表于: 2020-11-7 20:42 18772

[原创]Libc-Database 本地搭建实战

2020-11-7 20:42
18772

此处,我们以Ubuntu 16.04虚拟机为例讲述搭建方法,为防止环境冲突,请选择使用一台干净的虚拟机,若使用Ubuntu Server 16.04,可能会出现系统安装失败情况,若出现,请参考底部的参考链接。

另外,此教程中涉及到了部分文件的修改,我也对原项目进行了部分本地化,因此也可以直接获取我fork修改的项目进行搭建,项目地址:https://github.com/hebtuerror404/libc-database。欢迎Star~

本文中最后生成的配置结束的PVM虚拟机已上传至百度云盘,需要的自取即可,链接: https://pan.baidu.com/s/1mfG_ES4GzBrLyoGRerZDoA 密码: 9vpp

使用命令sudo apt-get update && sudo apt-get upgrade -y

⚠️:可以使用以下命令换源以加速下载

使用命令

使用命令

此处推荐使用以下命令直接获取docker

docker成功安装后可以去阿里云官网获取镜像加速器,然后按照官网所述直接做如下配置即可。

然后运行sudo pip install docker-compose -i https://mirrors.aliyun.com/pypi/simple/安装docker-compose

⚠️:此处安装完成后,可能产生以下错误

image-20200927180508318

此时可以使用which docker-compose来确定核心文件位置,然后建立符号链接即可。

首先运行以下命令获取nodejs

然后安装npm

image-20200927184204929

使用命令git clone https://github.com/niklasb/libc-database.git获取此项目。

修改libc-database/searchengine/frontend/src/App.js

接下来进入项目文件夹并生成Web端主项目

⚠️:若npm安装过慢,可以尝试使用cnpm,官网对于cnpm的描述如下:

要使用cnpm则运行以下命令:

⚠️:若可以在虚拟机内部开启VPN以加速访问境外网站,请在此步开启。

使用以下命令获取/更新所有libc文件到本地,此步骤依据网络连接状况需要耗时30 min ~ 2 h,请耐心等待

./get arch命令可能极其缓慢,属于正常情况,请耐心等待~

./get rpm命令可能会因cpio错误而退出,属于正常情况,直接无视即可~

首先需要修改一系列文件,使之满足启动条件

修改libc-database/searchengine/nginx.conf

修改libc-database/searchengine/config.py

修改libc-database/searchengine/api.py

使用命令sudo docker-compose up -d

启动后可以使用docker ps检查启动情况

image-20200928103911098

/libc-database/searchengine下,执行python3.6 -m index ../db

建立完成后,使用curl -XGET 127.0.0.1:9200/_cat/indices/来测试索引建立情况

image-20200928142936169

最后,在/libc-database/searchengine下使用/usr/sbin/nginx -c nginx.conf启动本地Ngnix服务

使用命令curl -X POST -H 'Content-Type: application/json' --data '{"symbols": {"strncpy": "db0", "strcat": "0x000000000d800"}}' http://127.0.0.1/api/find进行测试。

image-20200928143551542

断开虚拟机网络,以验证本地状态下的服务可用性

image-20200928144129824

执行下列命令即可

【原】光盘安装ubuntu出现BusyBox不能继续安装的终极解决方法

 
 
 
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo vi /etc/apt/sources.list
# vi 内运行以下两条命令
:% s/us.archive.ubuntu.com/mirrors.aliyun.com/g
:wq
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo vi /etc/apt/sources.list
# vi 内运行以下两条命令
:% s/us.archive.ubuntu.com/mirrors.aliyun.com/g
:wq
sudo apt-get install git vim wget curl python python3 python-pip python3-pip binutils file wget rpm2cpio cpio zstd nginx libffi6 libffi-dev software-properties-common -y
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt-get update
sudo apt-get install python3.6
sudo curl https://bootstrap.pypa.io/get-pip.py -o /get-pip.py
sudo python3.6 /get-pip.py
sudo ln -s /usr/local/bin/pip /usr/bin/pip
sudo apt-get install git vim wget curl python python3 python-pip python3-pip binutils file wget rpm2cpio cpio zstd nginx libffi6 libffi-dev software-properties-common -y
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt-get update
sudo apt-get install python3.6
sudo curl https://bootstrap.pypa.io/get-pip.py -o /get-pip.py
sudo python3.6 /get-pip.py
sudo ln -s /usr/local/bin/pip /usr/bin/pip
sudo pip install elasticsearch
sudo pip install elasticsearch
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://<镜像加速器ID>.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://<镜像加速器ID>.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
 
 
 
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
sudo apt-get install -y nodejs
curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo npm install -g n
sudo n latest
sudo npm install -g n
sudo n latest
import React, { useState, useEffect, useCallback, useRef } from 'react';
import './App.css';
import 'fontsource-roboto';
import Button from '@material-ui/core/Button';
import Grid from '@material-ui/core/Grid';
import TextField from '@material-ui/core/TextField';
import Link from '@material-ui/core/Link';
import CircularProgress from '@material-ui/core/CircularProgress';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableRow from '@material-ui/core/TableRow';
 
import { makeStyles } from '@material-ui/core/styles';
 
 
- const API_BASE = 'https://libc.rip/api';
+ const API_BASE = 'http://127.0.0.1/api';
 
const api = async (path, data) => {
  let resp = await fetch(`${API_BASE}${path}`, {
    method: 'POST',
    mode: 'cors',
    cache: 'no-cache',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data),
  });
  return await resp.json();
};
 
const useStyles = makeStyles((theme) => ({
  root: {
    '& .MuiTextField-root': {
      margin: theme.spacing(1),
    },
    '& .MuiButton-root': {
      margin: theme.spacing(1),
    },
    '& .remove': {
      marginTop: '1.2rem',
      height: '2rem',
    },
    '& .findbutton': {
      marginTop: '1.2rem',
    },
  },
  table: {
    marginTop: '1rem',
    marginBottom: '1rem',
  }
}));
 
 
function SearchRow({ onChange = () => {}, onRemove = () => {} }) {
  const [symbol, setSymbol] = useState("");
  const [address, setAddress] = useState("");
  const [addressValid, setAddressValid] = useState(true);
 
  const onSymbolChange = useCallback((evt) => {
    setSymbol(evt.target.value);
  }, []);
 
  const onAddressChange = useCallback((evt) => {
    setAddress(evt.target.value);
  }, []);
 
  useEffect(() => {
    const valid = !!address.match(/^(0x)?[0-9a-fA-F]*$/);
    setAddressValid(valid);
    onChange({valid, symbol, address});
  }, [address, symbol, onChange]);
 
  return (
    <div>
      <TextField label="Symbol name" value={symbol} onChange={onSymbolChange} />
      <TextField label="Address" error={!addressValid} value={address} onChange={onAddressChange} />
      <Button className="remove" variant="contained" color="secondary" onClick={onRemove}>
        Remove
      </Button>
    </div>
  );
}
 
function SearchForm({ onSearch = () => {} }) {
  const classes = useStyles();
  const [nextId, setNextId] = useState(0);
  const [rows, setRows] = useState([]);
  const [states, setStates] = useState({});
  const onRemoveRef = useRef();
  const onChangeRef = useRef();
 
  const makeRow = (id) => {
    return (
      <SearchRow key={id}
        onRemove={() => onRemoveRef.current(id)}
        onChange={(obj) => onChangeRef.current(id, obj)} />);
  };
 
  const isEmpty = useCallback((i) => {
    let state = states[rows[i].key];
    return !state || (!state.symbol && !state.address);
  }, [rows, states]);
 
  // Add new empty rows automatically
  useEffect(() => {
    let need = true;
    for (let i = 0; i < rows.length; ++i) {
      if (isEmpty(i)) {
        need = false;
        break;
      }
    }
 
    if (need) {
      setRows(rows => rows.concat([makeRow('' + nextId)]));
      setNextId(id => id + 1);
    }
  }, [rows, states, nextId, isEmpty]);
 
  // Remove superfluous rows at the end
  useEffect(() => {
    let i = rows.length - 1;
    while (i >= 1 && isEmpty(i) && isEmpty(i-1)) {
      --i;
    }
    if (i < rows.length - 1) {
      setRows(rows => rows.slice(0, i+1));
    }
  }, [rows, states, nextId, isEmpty]);
 
  const onRemove = useCallback((id) => {
    for (let i = 0; i < rows.length; ++i) {
      if (rows[i].key === id) {
        setRows(rows.slice(0, i).concat(rows.slice(i+1)));
        return;
      }
    }
  }, [rows]);
 
  const onChange = useCallback((id, obj) => {
    setStates({...states, [id]: obj});
  }, [states]);
 
  onChangeRef.current = onChange;
  onRemoveRef.current = onRemove;
 
  const onSubmit = useCallback(() => {
    let symbols = {};
    for (let row of rows) {
      let state = states[row.key];
      if (state && state.valid && state.address && state.symbol) {
        symbols[state.symbol] = state.address;
      }
    }
    onSearch({"symbols": symbols});
  }, [rows, states, onSearch]);
 
  const isValid = useCallback(() => {
    let cnt = 0;
    for (let row of rows) {
      let state = states[row.key];
      if (!state)
        continue;
      if (!state.valid)
        return false;
      if (state.address && state.symbol)
        cnt++;
    }
    return cnt > 0;
  }, [rows, states]);
 
  return (
    <form className={classes.root}>
      {rows}
 
      <div>
        <Button
          disabled={!isValid()}
          variant="contained"
          className="findbutton"
          color="primary"
          onClick={onSubmit}>
          Find
        </Button>
      </div>
    </form>
  );
}
 
function Result({ id, buildid, md5, symbols, download_url }) {
  const classes = useStyles();
  const [open, setOpen] = useState(false);
 
  const onToggle = useCallback((evt) => {
    evt.preventDefault();
    setOpen(!open);
  }, [open]);
 
  let symbolRows = Object.entries(symbols).map(([k, v]) => (
    <TableRow key={k}>
      <TableCell><code>{k}</code></TableCell>
      <TableCell><code>{v}</code></TableCell>
    </TableRow>
  ));
 
  return (
    <div>
      <Link href='#' onClick={onToggle}>{id}</Link>
      {open && (
        <Table size="small" className={classes.table}>
          <TableBody>
            <TableRow>
              <TableCell>Download</TableCell>
              <TableCell>
                <Link href={download_url} download>Click to download</Link>
              </TableCell>
            </TableRow>
            <TableRow>
              <TableCell>BuildID</TableCell>
              <TableCell>{buildid}</TableCell>
            </TableRow>
            <TableRow>
              <TableCell>MD5</TableCell>
              <TableCell>{md5}</TableCell>
            </TableRow>
            {symbolRows}
          </TableBody>
        </Table>
      )}
    </div>
  );
}
 
function App() {
  const [loading, setLoading] = useState(false);
  const [results, setResults] = useState(null);
 
  const onSearch = (data) => {
    setLoading(true);
    (async () => {
      try {
        setResults(await api('/find', data));
      } finally {
        setLoading(false);
      }
    })();
  };
 
  return (
    <div className="App">
      <p>Powered by the <Link href="https://github.com/niklasb/libc-database/tree/master/searchengine">libc-database search API</Link></p>
 
      <Grid container spacing={2}>
        <Grid item sm={12} md={6}>
          <h3>Search</h3>
          <SearchForm onSearch={onSearch} />
        </Grid>
        <Grid item sm={12} md={6}>
          <h3>Results</h3>
          {loading && <CircularProgress />}
          {results !== null && results.map(x => <Result {...x} />)}
        </Grid>
      </Grid>
    </div>
  );
}
 
export default App;
import React, { useState, useEffect, useCallback, useRef } from 'react';
import './App.css';
import 'fontsource-roboto';
import Button from '@material-ui/core/Button';
import Grid from '@material-ui/core/Grid';
import TextField from '@material-ui/core/TextField';
import Link from '@material-ui/core/Link';
import CircularProgress from '@material-ui/core/CircularProgress';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableRow from '@material-ui/core/TableRow';
 
import { makeStyles } from '@material-ui/core/styles';
 
 
- const API_BASE = 'https://libc.rip/api';
+ const API_BASE = 'http://127.0.0.1/api';
 
const api = async (path, data) => {
  let resp = await fetch(`${API_BASE}${path}`, {
    method: 'POST',
    mode: 'cors',
    cache: 'no-cache',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data),
  });
  return await resp.json();
};
 
const useStyles = makeStyles((theme) => ({
  root: {
    '& .MuiTextField-root': {
      margin: theme.spacing(1),
    },
    '& .MuiButton-root': {
      margin: theme.spacing(1),
    },
    '& .remove': {
      marginTop: '1.2rem',
      height: '2rem',
    },
    '& .findbutton': {
      marginTop: '1.2rem',
    },
  },
  table: {
    marginTop: '1rem',
    marginBottom: '1rem',
  }
}));
 
 
function SearchRow({ onChange = () => {}, onRemove = () => {} }) {
  const [symbol, setSymbol] = useState("");
  const [address, setAddress] = useState("");
  const [addressValid, setAddressValid] = useState(true);
 
  const onSymbolChange = useCallback((evt) => {
    setSymbol(evt.target.value);
  }, []);
 
  const onAddressChange = useCallback((evt) => {
    setAddress(evt.target.value);
  }, []);
 
  useEffect(() => {
    const valid = !!address.match(/^(0x)?[0-9a-fA-F]*$/);
    setAddressValid(valid);
    onChange({valid, symbol, address});
  }, [address, symbol, onChange]);
 
  return (
    <div>
      <TextField label="Symbol name" value={symbol} onChange={onSymbolChange} />
      <TextField label="Address" error={!addressValid} value={address} onChange={onAddressChange} />
      <Button className="remove" variant="contained" color="secondary" onClick={onRemove}>
        Remove
      </Button>
    </div>
  );
}
 
function SearchForm({ onSearch = () => {} }) {
  const classes = useStyles();
  const [nextId, setNextId] = useState(0);
  const [rows, setRows] = useState([]);
  const [states, setStates] = useState({});
  const onRemoveRef = useRef();
  const onChangeRef = useRef();
 
  const makeRow = (id) => {
    return (
      <SearchRow key={id}
        onRemove={() => onRemoveRef.current(id)}
        onChange={(obj) => onChangeRef.current(id, obj)} />);
  };
 
  const isEmpty = useCallback((i) => {
    let state = states[rows[i].key];
    return !state || (!state.symbol && !state.address);
  }, [rows, states]);
 
  // Add new empty rows automatically
  useEffect(() => {
    let need = true;
    for (let i = 0; i < rows.length; ++i) {
      if (isEmpty(i)) {
        need = false;
        break;
      }
    }
 
    if (need) {
      setRows(rows => rows.concat([makeRow('' + nextId)]));
      setNextId(id => id + 1);
    }
  }, [rows, states, nextId, isEmpty]);
 
  // Remove superfluous rows at the end
  useEffect(() => {
    let i = rows.length - 1;
    while (i >= 1 && isEmpty(i) && isEmpty(i-1)) {
      --i;
    }
    if (i < rows.length - 1) {
      setRows(rows => rows.slice(0, i+1));
    }
  }, [rows, states, nextId, isEmpty]);
 
  const onRemove = useCallback((id) => {
    for (let i = 0; i < rows.length; ++i) {
      if (rows[i].key === id) {
        setRows(rows.slice(0, i).concat(rows.slice(i+1)));
        return;
      }
    }
  }, [rows]);
 
  const onChange = useCallback((id, obj) => {
    setStates({...states, [id]: obj});
  }, [states]);
 
  onChangeRef.current = onChange;
  onRemoveRef.current = onRemove;
 
  const onSubmit = useCallback(() => {
    let symbols = {};
    for (let row of rows) {
      let state = states[row.key];
      if (state && state.valid && state.address && state.symbol) {
        symbols[state.symbol] = state.address;
      }
    }
    onSearch({"symbols": symbols});
  }, [rows, states, onSearch]);
 
  const isValid = useCallback(() => {
    let cnt = 0;
    for (let row of rows) {
      let state = states[row.key];
      if (!state)
        continue;
      if (!state.valid)
        return false;
      if (state.address && state.symbol)
        cnt++;
    }
    return cnt > 0;
  }, [rows, states]);
 
  return (
    <form className={classes.root}>
      {rows}
 
      <div>
        <Button
          disabled={!isValid()}
          variant="contained"
          className="findbutton"
          color="primary"
          onClick={onSubmit}>
          Find
        </Button>
      </div>
    </form>
  );
}
 
function Result({ id, buildid, md5, symbols, download_url }) {
  const classes = useStyles();
  const [open, setOpen] = useState(false);
 
  const onToggle = useCallback((evt) => {
    evt.preventDefault();
    setOpen(!open);
  }, [open]);
 
  let symbolRows = Object.entries(symbols).map(([k, v]) => (
    <TableRow key={k}>
      <TableCell><code>{k}</code></TableCell>
      <TableCell><code>{v}</code></TableCell>

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 3
支持
分享
最新回复 (2)
雪    币: 26245
活跃值: (63297)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
2
感谢分享!期待更多优秀文章!
2020-11-11 15:03
0
雪    币: 551
活跃值: (730)
能力值: ( LV3,RANK:24 )
在线值:
发帖
回帖
粉丝
3


最后于 2022-6-28 15:25 被柘狐编辑 ,原因:
2021-10-26 21:50
0
游客
登录 | 注册 方可回帖
返回
//