IDA pro 是一套很好用的反組譯程式,但是他把很重要的直接更改指令功能藏起來了,不能直接更改就只能看程式怎麼跑而已。如果有需要修改程式的話,只要
編輯 cfg/idagui.cfg
把 DISPLAY_PATCH_SUBMENU = NO
改成 DISPLAY_PATCH_SUBMENU = YES
這樣 edit/patch 就會出現,就能直接改程式碼了
2013/10/25
2013/10/24
替 VMWare 採用 LVM 的系統擴充硬碟空間
前提:你的 HOST 硬碟要夠大
第一步:擴展虛擬機器的硬碟空間
- 因為 LVM 只能使用 Primary Partition,一顆硬碟只能開四個,所以如果已經用掉四個 Primary Partition,請再增加一顆新的虛擬硬碟。
第二步:建立新的 LVM partition
- 執行 fdisk -l 查看目前的 partition 建立狀況
Device Boot Start End Blocks Id System
/dev/sda1 * 1 13 104391 83 Linux
/dev/sda2 14 1305 10377990 8e Linux LVM - 執行 fdisk /dev/sda (如果是第二顆硬碟要把 sda 改成 sdb,第三顆是 sdc,以此類推)
- 輸入 n add a new partition
- 輸入 p primary partition
- 如果已經有三個 primary partition,就沒得選只能建立第四個,否則看是要建立第幾個 primary partition 輸入其數字,如本例要輸入 3
- 輸入 t change a partition's system id
- 輸入剛才建立好的 partition 編號,如本例是 3
- 輸入 8e Linux LVM
- 輸入 w write table to disk and exit
- 執行 partprobe 免重開機立即套用 fdisk 的變更
- 執行 pvcreate /dev/sda3 建立實體 LVM (sda3 是剛才建立的 partition,請視情況改變)
第三步:把新的 LVM partition 加入現有 LVM Group
- 執行 lvs 檢視現有的 LVM 狀況
LV VG Attr LSize Origin Snap% Move Log Copy%
LogVol00 VolGroup00 -wi-ao 10.37G
留意 LogVol00 跟 VolGroup00 - 執行 vgextend VolGroup00 /dev/sda3 其中 VolGroup00 是要擴充的 LVM Group,sda3 是剛剛建立的 LVM partition
- 執行 vgdisplay 檢視 LVM Group 的狀況
--- Volume group ---
... ... 中間省略 ... ...
Free PE / Size 110 / 10.00 GB
留意 PE 的值 110 ,後面會用到 - 執行 lvresize -l +110 /dev/VolGroup00/LogVol00 其中 110 是剛才的 PE,VolGroup00 跟 LogVol00 用第一個指令查出來的
- 執行 resize2fs -p /dev/VolGroup00/LogVol00 變更 filesystem 的紀錄,變更後 df -h 才會看到新的容量。
第四步:開心使用新容量繼續剛剛因為容量不足而扼腕的工作
2013/06/27
Debian 讓 root 能跑 chromium
編輯 /etc/chromium/default
CHROMIUM_FLAGS 增加 --user-data-dir
存檔後就能用 root 打開 chromium
CHROMIUM_FLAGS 增加 --user-data-dir
存檔後就能用 root 打開 chromium
2013/03/20
CentOS 5 編譯及安裝 freeRadius 2.2.0
使用 freeRadius,本文使用版本 2.2.0
以下使用 CentOS 5 環境,以 root 登入
下載原始碼
wget ftp://ftp.freeradius.org/pub/freeradius/freeradius-server-2.2.0.tar.gz
解包
tar xzvf freeradius-server-2.2.0.tar.gz
config
cd freeradius-server-2.2.0
./configure --prefix=/
./configure --prefix=/
編譯
make
安裝
make install
啟動 radius 服務
radiusd -X
參數 -X 表示要顯示除錯資訊,並會強迫為 foreground,第一次執行會先建立 EAP 相關的檔案,最好是使用 -X 執行,檢視有沒有意外狀況發生。
之後執行只要執行 radiusd 就會以 daemon 的方式執行。
維護 /etc/raddb/clients.conf
原始的 localhost 設定,其中 secret 是這個 client 使用的通行碼。
client localhost { ipaddr = 127.0.0.1 secret = testing123 require_message_authenticator = no nastype = other }
再來一個給實際使用的範例,172.20.3.1/24 通行碼為 octtelradius
client 172.20.3.1/24 { secret = octtelradius shortname = my-pool }
維護 /etc/raddb/users
建立一個使用 pap 認證的 user
"octtel" Auth-Type := pap, Cleartext-Password := "22635986" Reply-Message = "Welcome %{User-Name}."
測試
radtest octtel 22635986 172.20.3.202 1812 octtelradius
Sending Access-Request of id 20 to 172.20.3.202 port 1812
User-Name = "octtel"
User-Password = "22635986"
NAS-IP-Address = 127.0.0.1
NAS-Port = 1812
Message-Authenticator = 0x00000000000000000000000000000000
rad_recv: Access-Accept packet from host 172.20.3.202 port 1812, id=20, length=37
Reply-Message = "Welcome octtel."
密碼錯誤的測試
radtest octtel badpass 172.20.3.202 1812 octtelradius
radtest octtel badpass 172.20.3.202 1812 octtelradius
Sending Access-Request of id 95 to 172.20.3.202 port 1812
User-Name = "octtel"
User-Password = "badpass"
NAS-IP-Address = 127.0.0.1
NAS-Port = 1812
Message-Authenticator = 0x00000000000000000000000000000000
rad_recv: Access-Reject packet from host 172.20.3.202 port 1812, id=95, length=37
Reply-Message = "Welcome octtel."
通行碼錯誤的測試
radtest octtel 22635986 172.20.3.202 1812 badsec
radtest octtel 22635986 172.20.3.202 1812 badsec
Sending Access-Request of id 78 to 172.20.3.202 port 1812 User-Name = "octtel" User-Password = "22635986" NAS-IP-Address = 127.0.0.1 NAS-Port = 1812 Message-Authenticator = 0x00000000000000000000000000000000 Sending Access-Request of id 78 to 172.20.3.202 port 1812 User-Name = "octtel" User-Password = "22635986" NAS-IP-Address = 127.0.0.1 NAS-Port = 1812 Message-Authenticator = 0x00000000000000000000000000000000 Sending Access-Request of id 78 to 172.20.3.202 port 1812 User-Name = "octtel" User-Password = "22635986" NAS-IP-Address = 127.0.0.1 NAS-Port = 1812 Message-Authenticator = 0x00000000000000000000000000000000 radclient: no response from server for ID 78 socket 3
2013/03/11
JDownloader 給 TP-Link TL-WR542G 用的重連指令
JDownloader 提供的無法使用,只好自己弄一個能用的。
[[[HSRC]]]
[[[STEP]]]
[[[REQUEST]]]
AUTH /? HTTP/1.1
Host: %%%routerip%%%
Authorization: Basic %%%basicauth%%%
[[[/REQUEST]]]
[[[/STEP]]]
[[[STEP]]]
[[[REQUEST]]]
GET /userRpm/StatusRpm.htm?ReleaseIp=Release&wan=1 HTTP/1.1
Host: %%%routerip%%%
[[[/REQUEST]]]
[[[/STEP]]]
[[[STEP]]]
[[[WAIT seconds="5"/]]]
[[[REQUEST]]]
GET /userRpm/StatusRpm.htm?RenewIp=Renew&wan=1 HTTP/1.1
Host: %%%routerip%%%
[[[/REQUEST]]]
[[[/STEP]]]
[[[/HSRC]]]
2013/01/28
Linux 的 contrack (使用 kernel 3.2)
一樣看 ipv4 的部份,hook 資訊在 ~/net/ipv4/netfilter/nf_contrack_l3proto_ipv4.c
static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
{
.hook= ipv4_conntrack_in,
.owner= THIS_MODULE,
.pf= NFPROTO_IPV4,
.hooknum= NF_INET_PRE_ROUTING, PRE_ROUTING 會呼叫 ipv4_conntrack_in()
.priority= NF_IP_PRI_CONNTRACK,
},{
NF_INET_LOCAL_OUT 對應 ipv4_conntrack_local
},{
NF_INET_POST_ROUTING 對應 ipv4_confirm
},{
NF_INET_LOCAL_IN 對應 ipv4_confirm
}
{
.hook= ipv4_conntrack_in,
.owner= THIS_MODULE,
.pf= NFPROTO_IPV4,
.hooknum= NF_INET_PRE_ROUTING, PRE_ROUTING 會呼叫 ipv4_conntrack_in()
.priority= NF_IP_PRI_CONNTRACK,
},{
NF_INET_LOCAL_OUT 對應 ipv4_conntrack_local
},{
NF_INET_POST_ROUTING 對應 ipv4_confirm
},{
NF_INET_LOCAL_IN 對應 ipv4_confirm
}
ipv4_conntrack_in() {
return nf_conntrack_in(); ~/net/netfilter/nf_conntrack_core.c
}
return nf_conntrack_in(); ~/net/netfilter/nf_conntrack_core.c
}
nf_conntrack_in() {
if (skb->nfct) { 封包的 conntrack 存在表示這個封包是 loopbak 或是 (untarcked?),直接略過
}
l3proto = __nf_ct_l3proto_find(); ipv4 傳入 PF_INET,ipv6 傳入 PF_INET6,這樣作以後就可以支援更多的第三層協議
ret = l3proto->get_l4proto(); 取得第四層協議編號
if (ret <= 0) {} 不認識的第四層協議就回報錯誤
l4proto = __nf_ct_l4proto_find(); l4 協議實作程式在 ~/net/netfilter/nf_conntrack_proto_XXX.c
例如:nf_conntrack_proto_tcp.c
其 ipv4 的相關資料定義在 struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4
其 ipv6 的相關資料定義在 struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6
if (l4proto->error != NULL) { 有宣告說要檢查錯誤的協議,->error 指向錯誤檢查 function
ret = l4proto->error(); 檢查封包是不是正常
if (ret <= 0) {} 檢查出錯誤就回報錯誤
}
ct = resolve_normal_ct(); 依據 l3 跟 l4 的協議資料獲取 conntrack
ret = l4proto->packet(); 進行 l4 的 packet
if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status))
nf_conntrack_event_cache(IPCT_REPLY, ct); 設置 contrack event
}
if (skb->nfct) { 封包的 conntrack 存在表示這個封包是 loopbak 或是 (untarcked?),直接略過
}
l3proto = __nf_ct_l3proto_find(); ipv4 傳入 PF_INET,ipv6 傳入 PF_INET6,這樣作以後就可以支援更多的第三層協議
ret = l3proto->get_l4proto(); 取得第四層協議編號
if (ret <= 0) {} 不認識的第四層協議就回報錯誤
l4proto = __nf_ct_l4proto_find(); l4 協議實作程式在 ~/net/netfilter/nf_conntrack_proto_XXX.c
例如:nf_conntrack_proto_tcp.c
其 ipv4 的相關資料定義在 struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4
其 ipv6 的相關資料定義在 struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6
if (l4proto->error != NULL) { 有宣告說要檢查錯誤的協議,->error 指向錯誤檢查 function
ret = l4proto->error(); 檢查封包是不是正常
if (ret <= 0) {} 檢查出錯誤就回報錯誤
}
ct = resolve_normal_ct(); 依據 l3 跟 l4 的協議資料獲取 conntrack
ret = l4proto->packet(); 進行 l4 的 packet
if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status))
nf_conntrack_event_cache(IPCT_REPLY, ct); 設置 contrack event
}
resolve_normal_ct() {
if (!nf_ct_get_tuple() {} 先把 tuple 找出來 hash = hash_conntrack_raw() 這兩行再把 hash 找出來
h = __nf_conntrack_find_get()
if (!h) {
h = init_conntrack() 如果沒有找到 hash 就建立一個新的 hash
}
ct = nf_ct_tuplehash_to_ctrack(h); 把 hash 轉成 conntrack
if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) {
方向是 Rep
} else {
方向是 Org,依據 ct->status 區分成三種狀態,ESTABLISHED、RELATED、NEW
} skb->nfct = &ct->ct_general; 這兩行將 ct 訊息回填 skb
skb->nfctinfo = *ctinfo;
}
if (!nf_ct_get_tuple() {} 先把 tuple 找出來 hash = hash_conntrack_raw() 這兩行再把 hash 找出來
h = __nf_conntrack_find_get()
if (!h) {
h = init_conntrack() 如果沒有找到 hash 就建立一個新的 hash
}
ct = nf_ct_tuplehash_to_ctrack(h); 把 hash 轉成 conntrack
if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) {
方向是 Rep
} else {
方向是 Org,依據 ct->status 區分成三種狀態,ESTABLISHED、RELATED、NEW
} skb->nfct = &ct->ct_general; 這兩行將 ct 訊息回填 skb
skb->nfctinfo = *ctinfo;
}
ipv4_conntrack_local() { /* root is playing with raw sockets. */
如果封包長度不符合 ip 的規定,那一定是 root 作 raw sockets 產生的
return nf_conntrack_in() 呼叫 nf_conntrack_in
}
如果封包長度不符合 ip 的規定,那一定是 root 作 raw sockets 產生的
return nf_conntrack_in() 呼叫 nf_conntrack_in
}
ipv4_confirm() { ct = nf_ct_get(skb, &ctinfo); 取得 conntrack
help = nfct_help(ct);
}
help = nfct_help(ct);
}
Linux 的 NAT (使用 kernel 3.2)
init: 以 ipv4 為例,初始化程式放置在 ~/net/ipv4/netfilter/nf_nat_rule.c
int __init nf_nat_rule_init(void)
ret = xt_register_target(&ipt_snat_reg); 註冊 snat 的 target
ret = xt_register_target(&ipt_dnat_reg); 註冊 dnat 的 target
int __init nf_nat_rule_init(void)
ret = xt_register_target(&ipt_snat_reg); 註冊 snat 的 target
ret = xt_register_target(&ipt_dnat_reg); 註冊 dnat 的 target
static struct xt_target ipt_snat_reg __read_mostly = {
.name= "SNAT",
.target= ipt_snat_target,
.targetsize= sizeof(struct nf_nat_multi_range_compat),
.table= "nat", table: nat,iptables 裡面用 -t nat 來使用
.hooks= (1 << NF_INET_POST_ROUTING) | (1 << NF_INET_LOCAL_IN), 只用到兩個 hook
.checkentry= ipt_snat_checkentry, 指定規則檢查函數,同樣實做在 nf_nat_rule.c
.family= AF_INET,
} dnat 只有 .hooks 跟 .checkentry 不同
.name= "SNAT",
.target= ipt_snat_target,
.targetsize= sizeof(struct nf_nat_multi_range_compat),
.table= "nat", table: nat,iptables 裡面用 -t nat 來使用
.hooks= (1 << NF_INET_POST_ROUTING) | (1 << NF_INET_LOCAL_IN), 只用到兩個 hook
.checkentry= ipt_snat_checkentry, 指定規則檢查函數,同樣實做在 nf_nat_rule.c
.family= AF_INET,
} dnat 只有 .hooks 跟 .checkentry 不同
ipt_snat_target() {
ct = nf_ct_get(skb, &ctinfo); 取得 conntrack 訊息
/* Connection must be valid and new. */ 作驗證
return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC);
}
ct = nf_ct_get(skb, &ctinfo); 取得 conntrack 訊息
/* Connection must be valid and new. */ 作驗證
return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC);
}
nf_nat_setup_info() { 實做在 ~/net/ipv4/netfilter/nf_nat_core.c
struct nf_conntrack_tuple ...; 定義在 ~/include/net/netfilter/nf_conntrack_tuple.h,用來作連線識別
nat = nfct_nat(ct); 從 conntrack 取出 nat 資訊
if (!nat) { 如果沒有,就新增一個
nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC);
}
nf_ct_invert_tuplepr(&curr_tuple, ...) 根據 reply 逆推當前的 tuple
get_unique_tuple(&new_tuple, ...) 獲取作過 snat 之後的 tuple
if (!nf_ct_tuple_equal(&new_tuple, &curr_tuple)) {
兩者不相等表示 tuple 發生變化了,要更新 conntrack 裡面 reply 的 tuple
}
if (maniptype == IP_NAT_MANIP_SRC) {
第一次作 NAT 必須將 ORIGINAL 的 tuple 加入 hash 列表
}
/* It's done. */ 打上 NAT 完成標記
}
struct nf_conntrack_tuple ...; 定義在 ~/include/net/netfilter/nf_conntrack_tuple.h,用來作連線識別
nat = nfct_nat(ct); 從 conntrack 取出 nat 資訊
if (!nat) { 如果沒有,就新增一個
nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC);
}
nf_ct_invert_tuplepr(&curr_tuple, ...) 根據 reply 逆推當前的 tuple
get_unique_tuple(&new_tuple, ...) 獲取作過 snat 之後的 tuple
if (!nf_ct_tuple_equal(&new_tuple, &curr_tuple)) {
兩者不相等表示 tuple 發生變化了,要更新 conntrack 裡面 reply 的 tuple
}
if (maniptype == IP_NAT_MANIP_SRC) {
第一次作 NAT 必須將 ORIGINAL 的 tuple 加入 hash 列表
}
/* It's done. */ 打上 NAT 完成標記
}
2013/01/17
get_vlan_id()
unsigned
short
get_vlan_id(
struct
sk_buff *skb)
{
struct
vlan_hdr *hdr;
unsigned
short
tci;
unsigned
short
id = 0;
if
(skb->protocol == cpu_to_be16(ETH_P_8021Q)) {
hdr = (
struct
vlan_hdr *)(skb->data);
tci = hdr->h_vlan_TCI;
id = (tci & VLAN_VID_MASK) >> 8;
}
return
id;
}
/* This function will return Vlan id of a skb. */
訂閱:
文章 (Atom)