반응형

문자열 압축 알고리즘의 설계와 구현

(1) 100 글자 이상이 포함되는 글을 입력받아 Huffman tree를 생성

(2) 입력 받은 글의 Huffman 코드를 출력

(3) 출력된 코드를 입력받아 문자열을 출력

 

728x90
반응형

'공부 > 자료구조' 카테고리의 다른 글

연산자 우선순위를 반영하는 산술식의 이진트리 설계와 구현  (0) 2021.05.09
탐색트리, 정렬 알고리즘과 계산시간 비교  (0) 2021.05.09
행렬곱  (0) 2021.05.09
다항식 연산  (0) 2021.05.09
정렬하기  (0) 2020.07.17
블로그 이미지

아상관없어

,
반응형

 

flex

import React from 'react';
import { StyleSheet, View, Text } from 'react-native';

export const Header = () => {
    return (
        <View style = {[styles.container, styles.header]}>
            <Text style={styles.text}>Header</Text>
        </View>
    );
};

export const Contents = () => {
    return (
        <View style={[styles.container, styles.contents]}>
            <Text style={styles.text}>Contents</Text>
        </View>
    );
};

export const Footer = () => {
    return (
        <View style ={[styles.container, styles.footer]}>
            <Text style={styles.text}>Footer</Text>
        </View>
    );
};




const styles = StyleSheet.create({
    container: {
        width: '100%',
        alignItems: 'center',
        justifyContent: 'center',
        height: 80,
    }, => contents와 text의 height는 80으로 고정

    header: {
        backgroundColor: '#f1c40f',
        height: 640,
    }, => header의 height는 640
    contents: {
        backgroundColor: '#3498db',
    },
    text: {
        fontSize: 26,
    },
});

=> 아이폰 11에서는 잘리지 않고 다 보이지만 에뮬레이터에선 잘려보인다.

 

flex를 이용하면 width, height와 달리 비율로 크기가 결정된다.

-flex의 값이 0일때는 설정된 width와 heigth값에 따라 크기가 결정

-양수일 경우 felx값에 비례하여 크기가 조정

ex)

(위의 코드에서 footer를 추가하는 것을 깜빡하였다.)

import React from 'react';
import { StyleSheet, View, Text } from 'react-native';

export const Header = () => {
    return (
        <View style = {[styles.container, styles.header]}>
            <Text style={styles.text}>Header</Text>
        </View>
    );
};

export const Contents = () => {
    return (
        <View style={[styles.container, styles.contents]}>
            <Text style={styles.text}>Contents</Text>
        </View>
    );
};

export const Footer = () => {
    return (
        <View style ={[styles.container, styles.footer]}>
            <Text style={styles.text}>Footer</Text>
        </View>
    );
};

const styles = StyleSheet.create({
    container: {
        width: '100%',
        alignItems: 'center',
        justifyContent: 'center',
        height: 80,
    },

    header: {
        flex: 1,
        backgroundColor: '#f1c40f',
        height: 640,
    },
    contents: {
        flex: 2,
        backgroundColor: '#3498db',
    },
    => 추가
    footer: {
        flex: 1,
        backgroundColor: '#1abc9c',
    },

    text: {
        flex: 3,
        fontSize: 26,
    },
});

1:2:1 비율로 나누어 채워지게 된다.

 

 

정렬

컴포넌트가 쌓이는 방향

- flexDirection사용

 

 

- justiftContent

 

flex-start : 시작점에서부터 정렬 (기본값)

flex-end : 끝에서부터 정렬

center : 중앙 정렬

space-between : 컴포넌트 사이의 공간을 동일하게 만들어서 정렬

space-around : 컴포넌트 각가의 주변 공간을 동일하게 만들어서 정렬

space-evenly : 컴포넌트 사이와 양 끝에 동일한 공간을 만들어서 정렬

 

- alignItems

 

flex-start : 시작점에서부터 정렬 (기본값)

flex-end : 끝에서부터 정렬

center : 중앙정렬

strecth : alignItems의 방향으로 컴포넌트 확장

baseline :  컴포넌트 내부의 텍스트 베이스라인을 기준으로 정렬

728x90
반응형

'공부 > 리액트 네이티브' 카테고리의 다른 글

스타일링  (0) 2021.05.08
리액트 네이티브 - 이벤트  (0) 2021.05.06
리액트 네이티브 - props  (0) 2021.05.06
리액트 네이티브 - props  (0) 2021.05.06
리액트 네이티브 - button 컴포넌트  (0) 2021.05.06
블로그 이미지

아상관없어

,
반응형

JSX는 backgroundColor와 같이 카멜 표기법으로 작성해야한다.

 

expo init react-native-style

./src/App.js 생성

 

 

인라인 스타일링

컴포넌트에 직접 스타일을 입력하는 방식

객체 형태로 전달

import React from 'react';
import { View, Text } from 'react-native';

const App = () => {
    return (
        <View
            style={{
                flex: 1,
                backgroundColor: '#fff',
                alignItems: 'center',
                justifyContent: 'center',
            }}
        >
            <Text
                style={{
                    padding: 10,
                    fontSize: 26,
                    fontWeight: '600',
                    color: 'black',
                }}
            >
                Inline Styling - Text 
            </Text>
            
            <Text
                style ={{
                    padding: 10,
                    fontSize: 26,
                    fontWeight: '400',
                    color: 'red',
                }}
            >
                Inline Styling - Error               
            </Text>
        </View>
    );
};

export default App;

 

 

명확하게 어떤 스타일인지 보이지만,

비슷한 역할을 하는 컴포넌트에 동일한 코드가 반복되고,

어떤 이유로 해당 스타일이 적용되었는지 가늠하기 힘듬

 

 클래스 스타일링

컴포넌트의 태그에 직접 입력 X

스타일 시트에 정의된 스타일을 사용

import React from 'react';
import { StyleSheet, View, Text } from 'react-native';

const App = () => {
    return (
        <View style = {styles.container}>
            <Text style = {styles.text}> Text </Text>
            <Text style = {styles.error}> Error </Text>
        </View>
    );
};


const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
        alignItems: 'center',
        justifyContent: 'center',
    },
=> padding, fontsize, fontweight, color를 지정한 이유를 보여줌
(예를 들어 색을 바꿀 때 text객체의 color만 바꾸어주면 되어 편함)
    text: {
        padding: 10,
        fontSize: 26,
        fontweight: '600',
        color: 'black',
    },
=> padding, fontsize, fontweight, color를 지정한 이유를 보여줌
    error: {
        padding: 10,
        fontSize: 26,
        fontWeight: '400',
        color: 'red',
    },

});


export default App;

 

여러개 스타일 적용

위의 text와 error는 중복된 스타일이 많음.

두 스타일 모두 Text 컴포넌트에 적용되는 스타일임

배열을 이용하여 여러 개의 스타일 적용

mport React from 'react';
import { StyleSheet, View, Text } from 'react-native';

const App = () => {
    return (
        <View style = {styles.container}>
            <Text style = {styles.text}> Text </Text>
            => 뒤에 오는 스타일이 앞에 있는 스타일을 덮음
            <Text style = {[styles.text,styles.error]}> Error </Text>
        </View>
    );
};


const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
        alignItems: 'center',
        justifyContent: 'center',
    },

    text: {
        padding: 10,
        fontSize: 26,
        fontweight: '600',
        color: 'black',
    },

    error: {
        fontWeight: '400',
        color: 'red',
    },

});


export default App;

 

 

 

상황에 따라 인라인, 클래스 스타일 방식 혼용

import React from 'react';
import { StyleSheet, View, Text } from 'react-native';

const App = () => {
    return (
        <View style = {styles.container}>
            <Text style = {[styles.tex, { color: 'green'}]}> Text </Text> <= 배열사용, 혼용
            <Text style = {[styles.text,styles.error]}> Error </Text>
        </View>
    );
};


const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
        alignItems: 'center',
        justifyContent: 'center',
    },

    text: {
        padding: 10,
        fontSize: 26,
        fontWeight: '600',
        color: 'black',
    },

    error: {
        fontWeight: '400',
        color: 'red',
    },

});


export default App;

 

 

 

 

 

 

외부 스타일 사용

만든 스타일을 다양한 곳에서 사용가능

외부 파일에 스타일을 정의하고 여러개의 파일에서 스타일을 공통으로 사용

./src/styles.js 생성

import {StyleSheet} from 'react-native';

export const viewStyles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
        alignItems: 'center',
        justifyContent: 'center',
    },
});

export const textStyles = StyleSheet.create({
    text: {
        padding: 10,
        fontSize: 26,
        fontWeight: '600',
        color: 'black',
    },

    error: {
        fontWeight: '400',
        color: 'red',
    },
});

//App.js


import React from 'react';
import { View, Text } from 'react-native';
import { viewStyles, textStyles } from './styles'; => ./styles에서 viewStyles, textStyles 가져옴


const App = () => {
    return (
        <View style = {viewStyles.container}>
            <Text style = {[textStyles.text, { color: 'green'}]}> Text </Text>
            <Text style = {[textStyles.text,textStyles.error]}> Error </Text>
        </View>
    );
};




export default App;

 

728x90
반응형

'공부 > 리액트 네이티브' 카테고리의 다른 글

스타일 속성  (0) 2021.05.09
리액트 네이티브 - 이벤트  (0) 2021.05.06
리액트 네이티브 - props  (0) 2021.05.06
리액트 네이티브 - props  (0) 2021.05.06
리액트 네이티브 - button 컴포넌트  (0) 2021.05.06
블로그 이미지

아상관없어

,
반응형

press 이벤트

onClick 과 비슷한 이벤트

TouchableOpacity 컴포넌트에서 설정할 수 있는 Press 이벤트의 종류는 4가지임

onPressIn : 터치가 시작될때 항상 호출

onPressOut : 터치가 해제될 때 항상 호출

onPress : 터치가 해제될때 onPressOut 이후 호출

onLongPress : 터치가 일정 시간 이상 지속되면 호출

import React from 'react';
import { TouchableOpacity, Text } from 'react-native'

const EventButton = () => {
    const _onPressIn = () => console.log('Press In!!\n');
    const _onPressOut = () => console.log('Press Out!!\n');
    const _onPress = () => console.log('Press !!\n');
    const _onLongPress = () => console.log('Long Press !!\n');


    return (
        <TouchableOpacity
            sytle={{
                backgroundCloer: '#f1c40f',
                padding: 16,
                margin: 10,
                borderRadius: 8,
            }}

            onPressIn={_onPressIn}
            onLongPress={_onLongPress}
            onPressOut={_onPressOut}
            onPress={_onPress}
        >
            <Text style={{color: 'white', fontSize: 24}}>Press</Text>
        </TouchableOpacity>
    );
};

export default EventButton;
import React from 'react';
import {View} from 'react-native';
import EventButton from './components/EventButton';

const App = () => {
    return (
        <View
            style={{
                flex: 1,
                backgroundColor: '#fff',
                alignItems: 'center',
                justifyContent: 'center',
            }}
        >
            <EventButton /> 

        </View>
    );
};


export default App;

 

 

change 이벤트

change는 값을 입력하는 TextInput 컴포넌트에서 많이 사용된다.

import React, { useState } from 'react';
import { View, Text, TextInput } from 'react-native';

const EventInput = () => {
    const [text, setText] = useState('');
    const _onChange = event => setText(event.nativeEvent.text);
    return(
        <View>
            <Text style = {{ margin: 10, fontSize: 30}}>text: {text}</Text>
            <TextInput
                style={{ borderWidth: 1, padding: 10, fontSize: 20}}
                onChange={_onChange}
            />
        </View>
    );
};

export default EventInput;

TextInput 

import React from 'react';
import {View} from 'react-native';
import EventButton from './components/EventButton';
import EventInput from './components/EventInput';

const App = () => {
    return (
        <View
            style={{
                flex: 1,
                backgroundColor: '#fff',
                alignItems: 'center',
                justifyContent: 'center',
            }}
        >

            <EventInput />

        </View>
    );
};


export default App;

 

 

 

728x90
반응형

'공부 > 리액트 네이티브' 카테고리의 다른 글

스타일 속성  (0) 2021.05.09
스타일링  (0) 2021.05.08
리액트 네이티브 - props  (0) 2021.05.06
리액트 네이티브 - props  (0) 2021.05.06
리액트 네이티브 - button 컴포넌트  (0) 2021.05.06
블로그 이미지

아상관없어

,
반응형

props : properties의 줄임마로, 부모 컴포넌트로부터 전달된 속성값 또는 상속받은 속성값을 말함.

부모 컴포넌트에서 자식 컴포넌트의 props를 설정하면 자식 컴포넌트에서는 해당 props를 사용할 수 있고, 수정은 부모 컴포넌트에서만 가능하다.

 

props 전달, 사용

App.js

import React from 'react';
import {Text, View} from 'react-native';
import MyButton from './components/MyButton';

const App = () => {
    return (
        <View
            style={{
                flex: 1,
                backgroundColor: '#fff',
                alignItems: 'center',
                justifyContent: 'center',
            }}
        >        
            <Text
                style={{
                    fontSize: 30,
                    marginBottom: 10,
                }}
            >
                Props
            </Text>
            //App컴포넌트에서 MyButton 컴포넌트를 호출할 때 title 속성에 Button이라는 문자열을 전달
            <MyButton title='Button' /> 
        </View>
    );
};

export default App;

MyButton.js

//리액트를 불러와서 사용할 수 있게 해줌(JSX는 React.createElement를 호출 하는 코드로 컴파일 되므로 반드시 작성)
import React from 'react';
//리액트 네이티브에서 제공되는 Pressable, Text 컴포넌트 추가
import{TouchableOpacity, Text} from 'react-native';

//Pressable 컴포넌틀르 사용해서 클릭에 대해 상호작용 할 수 있도록함.
//버튼에 내용표시하기위해 text컴포넌트 사용
//MyButton에서 부모로부터 전달된 props를 함수의 파라미터로 받음
const MyButton = props => {
	/*
    	console.log(porps);
        결과:
        Object { "title": "Button", }
    */
    return (
        <TouchableOpacity
            style={{
                backgroundColor: '#3498db',
                padding: 16,
                margin: 10,
                borderRaduis: 8,
            }}
            onPress={() => alert('click')}
        >
        	//props.title로 title값 읽어서 출력
            <Text style={{color: 'white', fotSize: 24}}>{props.title}</Text>
        </TouchableOpacity>
    );
};

export default MyButton;

MyButton의 이름이 props.title로 읽어들여 Button으로 되었다.

 

컴포넌트의 태그 사이에 값을 입력하여 전달할 수도 있다.

App.js
===============================================================
import React from 'react';
import {Text, View} from 'react-native';
import MyButton from './components/MyButton';

const App = () => {
    return (
        <View
            style={{
                flex: 1,
                backgroundColor: '#fff',
                alignItems: 'center',
                justifyContent: 'center',
            }}
        >        
            <Text style={{ fontSize: 30, marginBottom: 10, }}>
                Props
            </Text>
            <MyButton title="Button" /> 
            <MyButton title="Button">Children Props</MyButton> =>태그사이에 전달된 값은 자식 컴포넌트의 props의 children으로 전달됨
        </View>
    );
};

export default App;



MyButton.js
===============================================================
//리액트를 불러와서 사용할 수 있게 해줌(JSX는 React.createElement를 호출 하는 코드로 컴파일 되므로 반드시 작성)
import React from 'react';
//리액트 네이티브에서 제공되는 Pressable, Text 컴포넌트 추가
import{TouchableOpacity, Text} from 'react-native';

//Pressable 컴포넌틀르 사용해서 클릭에 대해 상호작용 할 수 있도록함.
//버튼에 내용표시하기위해 text컴포넌트 사용
const MyButton = props => {
    return (
        <TouchableOpacity
            style={{
                backgroundColor: '#3498db',
                padding: 16,
                margin: 10,
                borderRaduis: 8,
            }}
            onPress={() => alert('click')}
        >
            <Text style={{color: 'white', fotSize: 24}}>
                {props.children || props.title}
                </Text>
        </TouchableOpacity>
    );
};

export default MyButton;



props에 children이 있다면 title보다 우선시 되도록 작성

 

 

defaultProps

App.js에

버튼을 추가하고 아무런 값을 넘겨주지 않으면

<MyButton />

아무 표시가 되지 않는다. 

이러한 일을 방지하기 위해(반드시 전달되어야하는 값이 전달되게 설정)

MyButton.js에

MyButton.defaultProps = {

    title: 'Button',

};

를 추가하면 

MyButton 컴포넌트의 defaultProps 덕분에 기본으로 설정한 Button이 전달되었다.

 

 

 

 

propTypes

컴포넌트에 props를 전달할 때 잘못된 타입을 전달하거나, 필수로 전달해야하는 값을 전달하지 않았을 때

잘못된 props가 전달되었다고 경고하는 방법

컴포넌트에서 전달받아야하는 props의 타입과 필수 여부를 지정할 수 있음

 "npm install prop-types"

MyButton.js

MyButton.propTypes = {
	title: PropTypes.number,
};

title에 전달되어야 하는 값이 number라고 지정함

따라서 이전과 같이 String을 전달할 시 경고 메시지가 나타난다.

 

필수전달여부 => 선언된 타입 뒤에 isRequired만 붙여주면 된다.

MyButton.js

MyButton.propTypes = {
	title: PropTypes.string.isRequired,
    	name: PropTypes.string.isREquired,
};

App.js 에서 name을 전달해주지 않았으므로 에러가 발생하게 된다.

 

함수, 객체, 배열 등의 다양한 타입도 지정할 수 있다.

ex) onPress 필수로 지정

MyButton.js

MyButton.propTypes = {
	title: PropTypes.string.isRequired,
    	onPress: PropTypes.func.isRequired,
};
App.js

...
	    <MyButton title="Button" onPress={()=> alert("Click)}/> 
            <MyButton title="Button onPress={()=> alert("Click)}">
            	Children Props
            </MyButton> 
            <MyButton onPress={()=> alert("Click)}/>
....

 

 

 

 

useState

-State

컴포넌트 내부에서 생성되고 값을 변경할 수 있다.

이를 이용하여 컴포넌트 상태를 관리한다.

state : 컴포넌트에서 변화할 수 있는 값 ( 상태가 변하면 컴포넌트는 리렌더링 된다.)

 

 

useState는 상태를 관리하는 변수, 그 변수를 변경할 수 있는 setter 함수를 배열로 반환한다.

const [state, setState] = useState(initialState);

상태변수 state는 useState 함수에서 반환한 setter함수를 이용하여 변경하여야한다.

호출시 파라미터로 상태의 초기값을 전달한다.

(초기값을 전달하지 않으면 undefined로 설정되어 에러가 발생)

 

./src/component/Counter.js

import React, {useState} from 'react';
import { View, Text } from 'react-native';
import MyButton from './MyButton';

const Counter = () => {
    const [count, setCount] = useState(0);
    return (
        <View style={{ alignItems: 'center'}}>
            <Text style={{fontSize: 30, margin: 10}}>{count}</Text>
            <MyButton title = '+1' onPress={() => setCount(count + 1)} />
            <MyButton title = "-1" onPress={() => setCount(count - 1)} />
        </View>
    )
}

 

import React from 'react';
import {View} from 'react-native';
import Counter from './components/Counter';

const App = () => {
    return (
        <View
            style={{
                flex: 1,
                backgroundColor: '#fff',
                alignItems: 'center',
                justifyContent: 'center',
            }}
        >        
            <Text style={{ fontSize: 30, marginBottom: 10, }}>
                Props
            </Text>
            <MyButton title="Button" /> 
            <MyButton title="Button">Children Props</MyButton> 
            <MyButton />

            <counter /> <=counter 컴포넌트 추가

        </View>
    );
};


export default App;

 

 

728x90
반응형

'공부 > 리액트 네이티브' 카테고리의 다른 글

스타일링  (0) 2021.05.08
리액트 네이티브 - 이벤트  (0) 2021.05.06
리액트 네이티브 - props  (0) 2021.05.06
리액트 네이티브 - button 컴포넌트  (0) 2021.05.06
리액트 네이티브 - jsx  (0) 2021.05.06
블로그 이미지

아상관없어

,
반응형

props : properties의 줄임마로, 부모 컴포넌트로부터 전달된 속성값 또는 상속받은 속성값을 말함.

부모 컴포넌트에서 자식 컴포넌트의 props를 설정하면 자식 컴포넌트에서는 해당 props를 사용할 수 있고, 수정은 부모 컴포넌트에서만 가능하다.

 

props 전달, 사용

App.js

import React from 'react';
import {Text, View} from 'react-native';
import MyButton from './components/MyButton';

const App = () => {
    return (
        <View
            style={{
                flex: 1,
                backgroundColor: '#fff',
                alignItems: 'center',
                justifyContent: 'center',
            }}
        >        
            <Text
                style={{
                    fontSize: 30,
                    marginBottom: 10,
                }}
            >
                Props
            </Text>
            //App컴포넌트에서 MyButton 컴포넌트를 호출할 때 title 속성에 Button이라는 문자열을 전달
            <MyButton title='Button' /> 
        </View>
    );
};

export default App;

MyButton.js

//리액트를 불러와서 사용할 수 있게 해줌(JSX는 React.createElement를 호출 하는 코드로 컴파일 되므로 반드시 작성)
import React from 'react';
//리액트 네이티브에서 제공되는 Pressable, Text 컴포넌트 추가
import{TouchableOpacity, Text} from 'react-native';

//Pressable 컴포넌틀르 사용해서 클릭에 대해 상호작용 할 수 있도록함.
//버튼에 내용표시하기위해 text컴포넌트 사용
//MyButton에서 부모로부터 전달된 props를 함수의 파라미터로 받음
const MyButton = props => {
	/*
    	console.log(porps);
        결과:
        Object { "title": "Button", }
    */
    return (
        <TouchableOpacity
            style={{
                backgroundColor: '#3498db',
                padding: 16,
                margin: 10,
                borderRaduis: 8,
            }}
            onPress={() => alert('click')}
        >
        	//props.title로 title값 읽어서 출력
            <Text style={{color: 'white', fotSize: 24}}>{props.title}</Text>
        </TouchableOpacity>
    );
};

export default MyButton;

MyButton의 이름이 props.title로 읽어들여 Button으로 되었다.

 

컴포넌트의 태그 사이에 값을 입력하여 전달할 수도 있다.

App.js
===============================================================
import React from 'react';
import {Text, View} from 'react-native';
import MyButton from './components/MyButton';

const App = () => {
    return (
        <View
            style={{
                flex: 1,
                backgroundColor: '#fff',
                alignItems: 'center',
                justifyContent: 'center',
            }}
        >        
            <Text style={{ fontSize: 30, marginBottom: 10, }}>
                Props
            </Text>
            <MyButton title="Button" /> 
            <MyButton title="Button">Children Props</MyButton> =>태그사이에 전달된 값은 자식 컴포넌트의 props의 children으로 전달됨
        </View>
    );
};

export default App;



MyButton.js
===============================================================
//리액트를 불러와서 사용할 수 있게 해줌(JSX는 React.createElement를 호출 하는 코드로 컴파일 되므로 반드시 작성)
import React from 'react';
//리액트 네이티브에서 제공되는 Pressable, Text 컴포넌트 추가
import{TouchableOpacity, Text} from 'react-native';

//Pressable 컴포넌틀르 사용해서 클릭에 대해 상호작용 할 수 있도록함.
//버튼에 내용표시하기위해 text컴포넌트 사용
const MyButton = props => {
    return (
        <TouchableOpacity
            style={{
                backgroundColor: '#3498db',
                padding: 16,
                margin: 10,
                borderRaduis: 8,
            }}
            onPress={() => alert('click')}
        >
            <Text style={{color: 'white', fotSize: 24}}>
                {props.children || props.title}
                </Text>
        </TouchableOpacity>
    );
};

export default MyButton;



props에 children이 있다면 title보다 우선시 되도록 작성

 

 

defaultProps

App.js에

버튼을 추가하고 아무런 값을 넘겨주지 않으면

<MyButton />

아무 표시가 되지 않는다. 

이러한 일을 방지하기 위해(반드시 전달되어야하는 값이 전달되게 설정)

MyButton.js에

MyButton.defaultProps = {

    title: 'Button',

};

를 추가하면 

MyButton 컴포넌트의 defaultProps 덕분에 기본으로 설정한 Button이 전달되었다.

 

 

 

 

propTypes

컴포넌트에 props를 전달할 때 잘못된 타입을 전달하거나, 필수로 전달해야하는 값을 전달하지 않았을 때

잘못된 props가 전달되었다고 경고하는 방법

컴포넌트에서 전달받아야하는 props의 타입과 필수 여부를 지정할 수 있음

 "npm install prop-types"

MyButton.js

MyButton.propTypes = {
	title: PropTypes.number,
};

title에 전달되어야 하는 값이 number라고 지정함

따라서 이전과 같이 String을 전달할 시 경고 메시지가 나타난다.

 

필수전달여부 => 선언된 타입 뒤에 isRequired만 붙여주면 된다.

MyButton.js

MyButton.propTypes = {
	title: PropTypes.string.isRequired,
    	name: PropTypes.string.isREquired,
};

App.js 에서 name을 전달해주지 않았으므로 에러가 발생하게 된다.

 

함수, 객체, 배열 등의 다양한 타입도 지정할 수 있다.

ex) onPress 필수로 지정

MyButton.js

MyButton.propTypes = {
	title: PropTypes.string.isRequired,
    	onPress: PropTypes.func.isRequired,
};
App.js

...
	    <MyButton title="Button" onPress={()=> alert("Click)}/> 
            <MyButton title="Button onPress={()=> alert("Click)}">
            	Children Props
            </MyButton> 
            <MyButton onPress={()=> alert("Click)}/>
....

 

 

 

 

useState

-State

컴포넌트 내부에서 생성되고 값을 변경할 수 있다.

이를 이용하여 컴포넌트 상태를 관리한다.

state : 컴포넌트에서 변화할 수 있는 값 ( 상태가 변하면 컴포넌트는 리렌더링 된다.)

 

 

useState는 상태를 관리하는 변수, 그 변수를 변경할 수 있는 setter 함수를 배열로 반환한다.

const [state, setState] = useState(initialState);

상태변수 state는 useState 함수에서 반환한 setter함수를 이용하여 변경하여야한다.

호출시 파라미터로 상태의 초기값을 전달한다.

(초기값을 전달하지 않으면 undefined로 설정되어 에러가 발생)

 

./src/component/Counter.js

import React, {useState} from 'react';
import { View, Text } from 'react-native';
import MyButton from './MyButton';

const Counter = () => {
    const [count, setCount] = useState(0);
    return (
        <View style={{ alignItems: 'center'}}>
            <Text style={{fontSize: 30, margin: 10}}>{count}</Text>
            <MyButton title = '+1' onPress={() => setCount(count + 1)} />
            <MyButton title = "-1" onPress={() => setCount(count - 1)} />
        </View>
    )
}

 

import React from 'react';
import {View} from 'react-native';
import Counter from './components/Counter';

const App = () => {
    return (
        <View
            style={{
                flex: 1,
                backgroundColor: '#fff',
                alignItems: 'center',
                justifyContent: 'center',
            }}
        >        

            <counter /> <=counter 컴포넌트 추가

        </View>
    );
};


export default App;

 

728x90
반응형

'공부 > 리액트 네이티브' 카테고리의 다른 글

리액트 네이티브 - 이벤트  (0) 2021.05.06
리액트 네이티브 - props  (0) 2021.05.06
리액트 네이티브 - button 컴포넌트  (0) 2021.05.06
리액트 네이티브 - jsx  (0) 2021.05.06
리액트 네이티브  (0) 2021.05.02
블로그 이미지

아상관없어

,
반응형

컴포넌트 : 재사용 가능한 조립블록, 화면에 나타나는 UI 요소

App.js도 App이라는 컴포넌트이다.

부모로부터 받은 속성이나 자신의 상태에 따라 표현이 달라지고 다양한 기능 수행

 

 

내장 컴포넌트 => App.js의 View나 Text 컴포넌트가 대표적인 내장 컴포넌트

https://reactnative.dev/docs/compnents-and-apis

 

 

Button 컴포넌트

https://reactnative.dev/docs/button

 

./src/App.js

import React from 'react';
import {Text, View, Button} from 'react-native';

const App = () => {
    return (
        <View
        //style 정의
            style={{
                flex: 1,
                backgroundColor: '#fff',
                alignItems: 'center',
                justifyContent: 'center',
            }}
        >
            //출력될 text
            <Text style={{ fontSize: 30, marginBottom: 10 }}>Button Component</Text>
            //버튼에 출력될 text는 title 속성이용, 클릭시 click이 뜨도록 onPress 속성에 함수 지정
            <Button title="Button" onPress={() => alert('Click !!!')} />
        </View>
    );
};

export default App;

 

 

./App.js

import { StatusBar } from 'expo-status-bar';

import App from './src/App'; //./src/App 컴포넌트 사용

export default App;

(button 컴포넌트의 color 속성은 ios에서 텍스트 색을 나타내는 값, 안드로이드에서는 버튼의 바탕색을 나타내는 값)

 

 

 

 

커스텀 컴포넌트

TouchableOpacity 컴포넌트와 Text컴포넌트를 이용해서 MyButton 컴포넌트 생성

(리액트 네이티브 0.63버전에서 Pressable 컴포넌트가 TouchableOpacity컴포넌트를 대체함)

 

 

- ./src에 컴포넌트를 관리할 components 폴더 생성

- MyButton.js 생성

//리액트를 불러와서 사용할 수 있게 해줌(JSX는 React.createElement를 호출 하는 코드로 컴파일 되므로 반드시 작성)
import React from 'react';
//리액트 네이티브에서 제공되는 Pressable, Text 컴포넌트 추가
import{TouchableOpacity, Text} from 'react-native';

//Pressable 컴포넌틀르 사용해서 클릭에 대해 상호작용 할 수 있도록함.
//버튼에 내용표시하기위해 text컴포넌트 사용
const MyButton = () => {
    return (
        <TouchableOpacity>
            <Text style={{fontSize: 24}}>My Button</Text>
        </TouchableOpacity>
    );
};

export default MyButton;

- ./App.js 수정

import React from 'react';
import {Text, View} from 'react-native';
import MyButton from './components/MyButton';

const App = () => {
    return (
        <View
            style={{
                flex: 1,
                backgroundColor: '#fff',
                alignItems: 'center',
                justifyContent: 'center',
            }}
        >        
            <Text
                style={{
                    fontSize: 30,
                    marginBottom: 10,
                }}
            >
                My Button Component
            </Text>
            <MyButton />
        </View>
    );
};

export default App;

 

MyButton이 생성된다.

 

TouchableOpacity컴포넌트는 onPress 속성을 제공하는 TouchableWithoutFeedback 컴포넌트를 상속 받았기 때문에 onPress 속성을 지정하고 사용할 수 있음

//리액트를 불러와서 사용할 수 있게 해줌(JSX는 React.createElement를 호출 하는 코드로 컴파일 되므로 반드시 작성)
import React from 'react';
//리액트 네이티브에서 제공되는 Pressable, Text 컴포넌트 추가
import{TouchableOpacity, Text} from 'react-native';

//Pressable 컴포넌틀르 사용해서 클릭에 대해 상호작용 할 수 있도록함.
//버튼에 내용표시하기위해 text컴포넌트 사용
const MyButton = () => {
    return (
        <TouchableOpacity
            style={{
                backgroundColor: '#3498db',
                padding: 16,
                margin: 10,
                borderRaduis: 8,
            }}
            onPress={() => alert('click')}
        >
            <Text style={{color: 'white', fotSize: 24}}>My Button</Text>
        </TouchableOpacity>
    );
};

export default MyButton;

 

 

728x90
반응형

'공부 > 리액트 네이티브' 카테고리의 다른 글

리액트 네이티브 - props  (0) 2021.05.06
리액트 네이티브 - props  (0) 2021.05.06
리액트 네이티브 - jsx  (0) 2021.05.06
리액트 네이티브  (0) 2021.05.02
자바스크립트 - 정리  (0) 2021.04.30
블로그 이미지

아상관없어

,
반응형

컴포넌트 : 재사용할 수 있는 조립 블럭, 화면에 나타나는 UI요소라고 생각

와이어프레임 : 최종화면에 구성될 콘텐츠를 간단히 요약해서 보여주는 것

 

expo init react-native-component

 

App.js

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Open up App.js to start working on your app!</Text>
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

javascript 이지만 html과 같은 코드들이 보인다. 이러한 코드를 jsx라 한다.

jsx는 객체 생성과 함수 호출을 위한 문법적 편의를 제공하기 위해 만들어진 확장기능이다.

export default function App() {
 return (
   <Text>Open up App.js to start working on your app!</Text>
   <StatusBar style="auto" />
 )
}



위와 같이 App.js를 변경하면 
JSX 식에는 부모 요소가 하나 있어야 합니다.ts(2657)
와 같은 에러가 발생한다.

 

JSX에서는 여러개의 요소를 반환하는 경우에도 반드시 하나의 부모로 나머지 요소를 감싸서 반환해야한다.

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
 return (
   <View style={styles.container}>
    <Text>Open up App.js to start working on your app!</Text>
    <StatusBar style="auto" />
   </View>
 )
}

view는 UI를 구성하는 가장 기본적인 요소이다.

 

view 컴포넌트말고 여러 개의 컴포넌트를 반환하고 싶은 경우 Fragment 컴포넌트를 사용한다.

import { StatusBar } from 'expo-status-bar';
import React, {Fragment} from 'react';
import {Text} from 'reat-native';

export default function App() {
 return (
   <Fragment>
    <Text>Open up App.js to start working on your app!</Text>
    <StatusBar style="auto" />
   </Fragment>
 )
}

/*
==============
export default function App() {
 return (
   <>
    <Text>Open up App.js to start working on your app!</Text>
    <StatusBar style="auto" />
   </>
 )
}
와 같이 사용하여도 됨
*/

import React, {Fragment} from 'react';

Fragment를 사용하기 위해 import를 이용하여 불러오고 Fragment  컴포넌트를 사용하도록 함

 

 

<name 변수에 이름 넣어서 출력>

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import {StyleSheet, Text, View} from 'react-native';

export default function App() {
 const name = 'Changmin'
 return (
   <View style = {styles.container}>
     <Text style={styles.text}>My name is {name}</Text>
   </View>
 )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  text:{
    fontSize: 30,
  },
});

 

 

JSX내부에서 if문을 사용할 수 있지만 즉시실행함수 형태로 작성해야한다.

(즉시 실행 함수)

----------------------------------------------------------------------------

함수를 정의함과 동시에 바로 실행하는 함수

(function (name) { console.log('즉시실행함수' + name); })('foo'); 또는

- function 삭제 가능

( (name) => { console.log('즉시실행함수' + name); })();

----------------------------------------------------------------------------

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import {StyleSheet, Text, View} from 'react-native';

export default function App() {
 const name = 'abcd'
 return (
   <View style = {styles.container}>
     <Text style={styles.text}>
      {(() => {
        if (name === 'Changmin') return 'My name is Changmin';
        else if (name === 'Noname') return 'My name is Noname';
        else return 'My name is react-native';
      })()}
     </Text>
   </View>
 )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  text:{
    fontSize: 30,
  },
});

 

jsx에서는 false는 랜더링 되지 않는다.

따라서

name === 'name' && (실행할 코드)

name !== 'name' && (실행할 코드) 

처럼 특정 조건일때 컴포넌트의 랜더링 여부를 결정할 수 있다.

 

 

Inline 스타일링

jsx에서는 style에 문자열로 입력하는 것이 아니라 객체형태로 입력해야한다.

-으로 연결된 이름은 하이픈을 제거하고 카멜표기법으로 작성해야한다. camelCode

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import {Text, View} from 'react-native';

export default function App() {
 return (
   <View
      style = {{
        flex: 1,
        backgroundColor: '#fff',
        alignItems: 'ceonter',
        justifyContent: 'center',
      }}
    >
      <Text>Open up App.js to start working on your app!</Text>
    </View>
 )
}

728x90
반응형
블로그 이미지

아상관없어

,
반응형

- trainset.csv 파일을 이용하여 classification 모델 생성

- 모델을 이용하여 testset.csv 파일의 자료에 대한 class 예측

 

trainset.csv

(A열이 class label이다.)

 

testset.csv

 

- 예측결과 포맷

=========================================================================

model development process[Feature Selection -> Algorithm Selection -> Hyper parameter tuning] 순이므로, 먼저 어떠한 Feature을 고를 것인지 결정하였습니다.

Feature Selection 방법으로 강의에서 배운 filter method, backward elimination, forward selection 세가지 방법으로 테스트를 하였습니다. Feature selection을 하기 위해 model을 선택하여야 했는데, 이는 강의에서 배운 model comparison을 통하여 선정하였습니다.

기존에 배운 분류 알고리즘인 DecisionTreeClassifier, KNeighborsClassifier, RandomForestClassifier, SVC 외에 검색을 통하여 몇 가지 알고리즘을 추가하였습니다. 자주 사용되는 Xgboost, xgboost의 느린 단점을 보완한 LightGBM을 추가하여 비교를 하였습니다. (pip install 명령어를 사용하여 설치함)

5번 반복하여 비교한 결과 RandomForestxgboost, LightGBM이 모델 변동폭이 작고 정확도도 높은 것을 알 수 있어 이 3가지 모델을 사용하여 비교해보기로 하였습니다.

from sklearn.model_selection import RandomizedSearchCV
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import train_test_split
from xgboost import plot_importance

# Model comparison 
import matplotlib.pyplot as plt
from sklearn import model_selection

# from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from xgboost import XGBClassifier
from lightgbm import LGBMClassifier
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import KFold
from sklearn.metrics import accuracy_score
import pandas as pd
import numpy as np
import pprint as pp

#1. 데이터 셋 준비
data = pd.read_csv('C:\dataset/trainset.csv')

#2. 설명변수 반응 변수 나눔
data_x = data.iloc[:, 1:32]
data_y = data.iloc[:, 0]

# train, test 나눔
train_X, test_X, train_y, test_y = train_test_split(data_x, data_y, test_size=0.3,random_state=1234) 



# prepare configuration for cross validation test harness
seed = 7

# prepare models
models = []
models.append(('KNN', KNeighborsClassifier()))
models.append(('DT', DecisionTreeClassifier()))
models.append(('RF', RandomForestClassifier()))
models.append(('SVM', SVC()))
models.append(('xgboost', XGBClassifier()))
models.append(('LGBM', LGBMClassifier()))
results = []
names = []
scoring = 'accuracy'

for name, model in models:
    kfold = model_selection.KFold(n_splits=10, random_state=seed, shuffle=True)
    cv_results = model_selection.cross_val_score(model, data_x, data_y, cv=kfold, scoring=scoring)
    results.append(cv_results)
    names.append(name)
    msg = "%s: %f (%f)" % (name, cv_results.mean(), cv_results.std())
    print(msg)
    
print(results)

# average accuracy of classifiers
for i in range(0,len(results)):
    print(names[i] + "\t" + str(round(np.mean(results[i]),4)))
    
# boxplot algorithm comparison
fig = plt.figure()
fig.suptitle('Algorithm Comparison')
ax = fig.add_subplot(111)
plt.boxplot(results)
ax.set_xticklabels(names)
plt.show()

그리고 filter method, backward elimination, forward selection을 통하여 feature을 선정하였습니다.

(먼저 데이터 셋의 column name이 없어 0부터 숫자를 순서대로 할당하여 보기 편하게 하였습니다. Backward n_features_to_select=4, Cv=5)

 

[모델 선택하기 위해 비교]

 

LighGBM의 경우

[filter method]

“0.9159”

[backward elimination]

“0.7869”

 

[forward selection]

“0.871”

 

 

 

 

RandomForest의 경우

[filter method]

“0.909”

[backward elimination]

“0.849”

 

[Forward selection]

“0.871”

 

 

 

 

 

Xgboost의 경우

[filter method]

“0.907”

 

[backward elimination]

“0.850”

 

[Forward selection]

“0.872”

 

각기 다른 모델을 사용해도 feature의 중요도는 바뀌질 않으니 빠른 lightGBM 모델로 backward, forward selection에서 각 인자 n_features_to_select, k_features의 수를 filter method 에서 얻은 데이터를 바탕으로 수정하여 한번 더 테스트 하였습니다.

Filter method의 결과를 보면 선택하는 feature의 수가 많아질수록 정확도가 높아지므로 개수를 크게 변화가 없어지는 21개부터 30개까지 테스트를 해보았습니다.

하지만 forward selction을 할 경우 시간이 오래 걸리고 컴퓨터도 간헐적으로 멈추어 backward elimination으로 테스트하였습니다.

 

 

# Feature selection Example
import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score

from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier

from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.preprocessing import LabelEncoder
#from xgboost import XGBClassifier
from lightgbm import LGBMClassifier

#1. 데이터 셋 준비
name = []
for i in range(0,32):
    name.append(i)  
data = pd.read_csv('C:\dataset/trainset.csv', names = name)
print(data.head())
#2. 설명변수 반응 변수 나눔
data_x = data.iloc[:, 1:32]
data_y = data.iloc[:, 0]
# whole features
model = LGBMClassifier()
scores = cross_val_score(model, data_x, data_y, cv=5)
print("Acc: "+str(scores.mean()))
print('######################################################################')
print('# feature selection by filter method')
print('######################################################################')
######################################################################
# feature selection by filter method
######################################################################
# feature evaluation method : chi-square
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
test = SelectKBest(score_func=chi2, k=data_x.shape[1])
fit = test.fit(data_x, data_y)

# summarize evaluation scores
print(np.round(fit.scores_, 3)) #소수점 3자리까지 반올림
f_order = np.argsort(-fit.scores_) # sort index by decreasing order
sorted_columns = data.columns[f_order]
f_order
data_x.shape[1]
# test classification accuracy by selected features
model = XGBClassifier()

for i in range(0, data_x.shape[1]):
    fs = sorted_columns[0:i]
    data_x_selected = data_x[fs]
    scores = cross_val_score(model, data_x_selected, data_y, cv=5)
    print(fs.tolist())
    print(np.round(scores.mean(), 4))

'''
for i in range(20, 31):
    
    print('index = ', i)
'''
    ######################################################################
    # Backward elimination (Recursive Feature Elimination)
    ######################################################################
    from sklearn.feature_selection import RFE
    
model = LGBMClassifier()
    rfe = RFE(model, n_features_to_select=i)
    fit = rfe.fit(data_x, data_y)
    print("Num Features: %d" % fit.n_features_)
    fs = data_x.columns[fit.support_].tolist() # selected features
    print("Selected Features: %s" % fs)
    scores = cross_val_score(model, data_x[fs], data_y, cv=5)
    print("Acc: "+str(scores.mean()))



    print('######################################################################')
    print('# Forward selection')
    print('######################################################################')
    ######################################################################
    # Forward selection
    ######################################################################
    # please install 'mlxtend' moudle
    from mlxtend.feature_selection import SequentialFeatureSelector as SFS
    model = LGBMClassifier()
    sfs1 = SFS(model, k_features=i, n_jobs=-1, scoring='accuracy', cv=5)
    sfs1 = sfs1.fit(data_x, data_y, custom_feature_names=data_x.columns)
    sfs1.subsets_ # selection process
    sfs1.k_feature_idx_ # selected feature index
    print(sfs1.k_feature_names_)# selected feature name
    
    

Backward elimination을 하였을 때

 

Feature25개 사용하면 정확도가 0.9165으로 가장 좋았지만, 나머지와 비교하였을 때 filter method도 그러하듯이 feature 개수에 따른 큰 차이를 보여주지 못하여 테스트 시 모든 feature들을 사용하기로 결정하였습니다.

 

이제 hyperparameter 튜닝을 하기 전 각 모델별로 테스트를 해보았다.

 

Feature을 선정하기 위한 과정에서 model도 함께 선정하였으므로 다음으로 hyperparameter tuning을 진행하였습니다. Hyper parameter를 찾기 위해 RandomizedSearchCV 방법을 사용하였습니다.

 

(다른 최적화 방법 BaysianOptimizaion을 찾았으나 정확한 사용법을 익히지 못하여 RandomizedSearchCV 방법을 사용하였습니다.

또한 autosklearn을 통하여 최적의 모델을 찾고 hyper parameter 최적값을 찾는 과정을 자동으로 해주려 하였으나, 다음의 글을 찾아Anaconda does not ship auto-sklearn, and there are no conda packages for auto-sklearn” 이 방법은 해보지 못하였습니다.

-Xgboost

max_depth(int, default: 3): 기본 학습자를 위한 최대 트리 깊이

learning_rate(float, default: 0.1) : Boosting 학습률

n_estimators(int, default: 100) : fit하기 위한 Boosted tree

silent(boolean, default: True : Boosting 실행하는 동안 메시지를 print할지 여부

objective(string or callable, default:’reg:linear’) : 학습할 Objective Function 사용

booster(string, default: ‘gbtree’): Booster 사용할 모드 gbtree, gblinear, dart

nthread(int, default: ‘None’): xgboost 실행하는데 사용할 병렬 스레드

- xgboost.XGBClassifier(nthread=20)

n_jobs(int, default: 1): xgboost 실행하는데 사용할 병렬 스레드

gamma(float, default: 0): 트리의 leaf 노드에 추가 파티션(partition) 만들때 최소 손실 감소(Minimum loss reduction) 필요하다.

min_child_weight(int, default: 1): Child 노드에 필요한 instance weight(hessian) 최소 합계

max_delta_step(int): Tree 가중치(Weight) 추정을 허용하는 최대 Delta 단계

subsample(float): 학습(Training) Instance Subsample 비율

colsample_bytree(float): Tree 구성할 column Subsample 비율

colsample_bylevel(float): Tree Level에서 분할(split) 대한 column Subsample

 

처음햇을 때

 

max_depth를 늘리니 향상되는 것을 알 수 있었다.

따라서 max_depth를 더 늘려 테스트해보려 하였지만, 실수로 n_estiators np.linspace(start = 200, stop = 10000, num = 21)와 같이 늘려서 테스트 하였다.

시간은 2시간 가량 걸렸지만, n_estimators의 값은 크게 영향이 없다는 것을 알았다.

Max_depth값이 늘어났을 때 성능이 향상되는 것을 알 수 있었다.

 

np.linspace(4000, 10000, num = 11)로 바꾸어 하였을 때,

비슷한 향상 폭을 보여주었다.

 

 

-RandomForest

예제코드와 같이 실행을 하면

1.21%의 향상을 얻을 수 있었습니다.

 

위와 같이 각 모델에 대해 HyperParameter를 진행하려하였으나,

tuningparameter들의 수가 많고 tuning을 하는 과정도 상당한 시간이 걸려,

시간 비용을 줄이고자 분산이 적고 예측력이 세가지 모델 중 가장 좋은 LightGBM을 선택하여 hyper parameter tuning을 하고 테스트를 진행하였습니다.

=========================================================================

 

초반에는 여러 데이터들의 범위를 바꾸어 가면서 테스트를 하였습니다.

2000 candidates를 하였지만 시간대비 좋지 않은 결과를 얻었다.

Xboost에서 max_depth가 커지면서 좋아진 것을 보고 LightGBM에서도 값을 크게 잡아서 테스트를 하였다.

Candidates100이지만 성능이 더 좋아진 것으로 보아 candidate를 크게 잡을 필요가 없다고 생각하였습니다.

 

그리고 num_leaves를 바꾸어 테스트하였으나 결과에 변화가 없는 것으로 보아 num_leaves는 큰 영향을 끼치지 않는 것으로 확인했다.

min_data_in_leaf가 커지면 향상 폭이 줄어드는 것을 확인하였다.

 

따라서 max_depth가 크면 향상 폭이 가장 좋아지는 것으로 판단하였다.

parameter들을 범위를 넓혀 가면서 테스트를 하였다.

범위를 넓게 한 경우

 

그리고 default parameter를 사용할 때와 0.82%의 향상이 있었던 파라미터를 사용하여 테스트해보았습니다.

Default의 경우 0.93이 나왔고, 향상된 파라미터를 사용할 경우 0.90으로 줄어들었습니다. 과적합이 의심되어 max_depth값을 낮추어 다시 테스트하니 0.93이 나온 것을 알 수 있었습니다. 따라서 과적합과 같은 경우를 고려하기 위하여 과적합을 줄일 수 있는 요소를 찾아보았습니다.

https://greeksharifa.github.io/machine_learning/2019/12/09/Light-GBM/http://machinelearningkorea.com/2019/09/29/lightgbm-%ED%8C%8C%EB%9D%BC%EB%AF%B8%ED%84%B0/를 참고하여 사용할 파라미터를 선정하였습니다.

 

그리고 여러 parameter들을 종합적으로 테스트를 하면 각 요소들이 얼만큼 차이를 내는지 파악하기 힘들어 parameter 하나씩 테스트를 하였습니다.

 

 

다음과 같이 범위를 좁혀나가며 best Parameter에 근접한 범위로 좁혀가면서 최적 값을 찾아보았습니다. 그리고 과적합을 조절할 파라미터들은 max_depth와 함께 테스트하였습니다.

하지만 다른 파라미터들과 함께 테스트하였을 때 좋지 않은 결과를 보여주기도 하였습니다.

 

사이트를 통하여 테스트시 0.93

 

 

적절한 max_depth를 찾으려 하였으나, 초기에 max_depth값 테스트를 해보기위해 설정했던 max_depth = 90, learning_rate = 0.1, n_estimators = 300이 가장 좋은 결과를 보여주었습니다. 아마 과적합이 일어나면서 확률이 좋아진 것으로 예상합니다. 과적합을 줄이면서 좋은 성능을 내는 파라미터를 찾기 어려웠습니다. 따라서 n_iter의 값을 늘리고 max_depth, n_estimators의 값을 줄여서 테스트 하였습니다.

여러 번 testset으로 예측한 결과 max_depthlearning_rate, n_estimators의 값을 변경한 경우가 0.93으로 더 좋은 예측을 보여주어 다른 값보다 이 3가지 값을 변경시켜 더 테스트 해보기로 하였습니다. 범위를 넓히고 과적합을 줄이기 위해 범위를 줄이면서, n_iter1000으로 늘려 여러 값들을 테스트해보았습니다.

그래도 변화가 없어 0.43%가 나왔던 범위를 선택하고 나머지 parameter들을 추가하여 다시 테스트해 보았습니다. 

0.92로 향상은 없었습니다.

Hyper parameter값들을 여러가지로 조정해보고 testset을 적용하여 정확도를 보았을때, acc : 0.929039301310044 가 가장 좋은 결과를 보여주었습니다.

 

###HYPERPAMETER TUNING####
from sklearn.model_selection import RandomizedSearchCV
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import train_test_split
# Model comparison 
import matplotlib.pyplot as plt
from sklearn import model_selection
# from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.preprocessing import LabelEncoder
from xgboost import XGBClassifier
import lightgbm as lgb
from lightgbm import LGBMClassifier
from bayes_opt import BayesianOptimization
from hyperopt import fmin, tpe, hp

import pandas as pd
import numpy as np
import pprint as pp

'''
HI, PH, GR, PH, EL, MI, PH, MI, CO, EL, GR....
1. feature selecion

2. algorithm selection

3. hyper parameter tuning
randomizedserchcv 가 조합을 자동으로 골라주고, 시간이 줄어드므로 사용함.
'''

#1. 데이터 셋 준비
data = pd.read_csv('C:\dataset/trainset.csv')

#2. 설명변수 반응 변수 나눔
data_x = data.iloc[:, 1:32]
data_y = data.iloc[:, 0]

data_x
# train, test 나눔
train_X, test_X, train_y, test_y = train_test_split(data_x, data_y, test_size=0.3, random_state=1234) 


base_model = LGBMClassifier(random_state=1234)
base_model.fit(train_X, train_y)
base_accuracy = base_model.score(test_X, test_y)
print(base_accuracy)

n_estimators = [int(x) for x in np.linspace(start = 200, stop = 600, num = 41)]
# Maximum number of levels in tree
max_depth = [int(x) for x in np.linspace(1, 400, num = 41)]
#하나의 트리가 가지는 최대 리프 개수
#num_leaves = [int(x) for x in np.linspace(2, 1000, num = 31)]

#리프 노드가 되기 위한 최소한의 샘플 데이터 수
#min_child_samples  = [int(x) for x in np.linspace(1, 100, num = 11)]

learning_rate = [float(x) for x in np.linspace(0.000001, 0.5, num = 41)]



#데이터 샘플링 비율 0이되면 안됨
#bagging_fraction = [float(x) for x in np.linspace(0.1, 1, num = 11)]

#개별 트리 학습시 선택되는 피처 비율 - 과적합 방지
#feature_fraction = [float(x) for x in np.linspace(0.000001, 1, num = 11)]

#과적합을 제어하기 위해 데이터를 샘플링하는 비율
#subsample  = [float(x) for x in np.linspace(0.000001, 1, num = 11)
#metric = ['multiclass']

# Create the random grid
random_grid = {'n_estimators' : n_estimators,
               'max_depth' : max_depth,
               #'feature_fraction': feature_fraction,
               #'subsample' : subsample,
               'learning_rate' : learning_rate
               #'bagging_fraction' : bagging_fraction,
               #'num_leaves' : num_leaves,
               #'min_child_samples' : min_child_samples,
              # 'metric' : metric
               }

pp.pprint(random_grid)


'learning_rate' : learning_rate
               #'bagging_fraction' : bagging_fraction,
               #'num_leaves' : num_leaves,
               #'min_child_samples' : min_child_samples,
              # 'metric' : metric
               }

pp.pprint(random_grid)

# Use the random grid to search for best hyperparameters
rf = LGBMClassifier(random_state=1234)
rf_random = RandomizedSearchCV(estimator = rf, param_distributions = random_grid, n_iter = 1000, cv = 5, verbose=2, random_state=42, n_jobs = -1)

# Fit the random search model
rf_random.fit(train_X, train_y)

# best parameters
# best_params에 최적 조합이 저장됨
pp.pprint(rf_random.best_params_)


# best model
#best_estimator => 최적 조합을 적용해서 만들어진 모델
best_random_model = rf_random.best_estimator_
best_random_accuracy = best_random_model.score(test_X, test_y)

print('base acc: {0:0.2f}. best acc : {1:0.2f}'.format( \
base_accuracy, best_random_accuracy))
print('Improvement of {:0.2f}%.'.format( 100 * \
(best_random_accuracy - base_accuracy) / base_accuracy))

 

 

######testset save to csv#######
from lightgbm import LGBMClassifier
import pandas as pd
import numpy as np

#1. 데이터 셋 준비
data = pd.read_csv('C:\dataset/trainset.csv', header=None)
test_x = pd.read_csv('C:\dataset/testset.csv', header=None)

data.shape
test_x.shape
#2. 설명변수 반응 변수 나눔
data_x = data.iloc[:, 1:32]
data_y = data.iloc[:, 0]

data_x
data_y

model = LGBMClassifier(learning_rate = 0.1, max_depth = 90, n_estimators = 300)
model.fit(data_x, data_y)

pred_y = model.predict(test_x)

result = pd.DataFrame(pred_y)
result.to_csv('lightgbm.csv', header=None, index=False)

 

 

후기)

먼저 그래프로 모델을 비교하여 해당 데이터에 어떤 모델이 가장 잘 맞는지 고르는 것이 전반적인 예측율에 많은 영향을 끼친다고 느꼈다. 그리고 적절한 feature을 찾기 위해 시간이 빠른 모델을 사용하여 테스트를 하면 시간을 줄일 수 있고 hyper parameter를 찾기 위한 여러가지 방법들을 알게 되었다.

 

이번 경진대회에서는 RandomizedSearchCV를 사용하였다. 이 방법으로 적절한 hyper parameter를 찾기 위해 parameter 별로 값을 바꾸어 테스트를 해보고, 여러 parameter들을 동시에 바꾸어 가며 테스트를 하였다.

또한 n_iter을 높일수록 과적합을 줄여 향상이 더 줄어들 수 있다는 것도 알게 되었다. 하지만 적절한 값을 찾는 것이 매우 힘들었다. Parameter를 바꿀 때 이것이 향상되었는지 과적합인지, 과소적합인지를 구분하기가 힘들었다.

처음에 1.38%의 향상을 보았지만 그 값은 과적합으로 인해 예측은 좋지 못하였고, 오히려 max_depth를 낮추니 결과가 좋아지는 경우를 보았다. 또한 test_size 비율을 바꿔가며 나온 결과값을 테스트해보았지만 좋은 결과를 얻기는 어려웠다.

따라서 이런 튜닝을 하는 과정은 소모적이며 때론 2시간 이상이 걸릴 만큼, 시간이 많이 들고 적절한 값을 찾는 것은 감에 의존하고 우연에 의존한다는 생각을 하였다. 이런 과정을 편하게 해주는 방법들이 없을까 찾아보았고, hyper parameter가 변경될 때마다 정확도의 변화를 그래프로 보여주던가, 과적합을 판단할 수 있게 과적합 수치도 함께 보여준다면 더 편리할 것이라 생각하였다.

 

AutoML은 데이터의 특성에 따라 좋은 알고리즘과 어울리는 파라미터들을 자동화하여 찾아준다.

그 중 Auto-sklearn라는 방법이 있다. 데이터가 들어오면, 데이터에 맞을만한 알고리즘, parameter를 알려주는 meta-learning process를 진행하고 이 결과로 알고리즘과 parameter set들을 추천해 준다. 그 후 앙상블 기법을 활용해 추천된 알고리즘, parameter set들의 최적화를 진행합니다. 하지만 Anaconda does not ship auto-sklearn, and there are no conda packages for auto-sklearn” 와 같은 답변을 얻어 실제로 해보진 못하였다.

그리고 Bayesian Optimization을 통하여 hyper parameter의 최적값을 탐색할 수 있다. Bayesian Optimization은 매 회 새로운 hyper parameter값에 대한 조사를 수행할 시, 사전지식을 충분히 반영하면서 전체적인 탐색 과정을 체계적으로 수행할 수 있는 방법론이다. 따라서 이 방법을 통하여 hyper parameter를 찾으려 하였다. 하지만 완벽히 이해하지 못하였고, 관련 자료를 많이 찾지 못하여 사용법과 에러에 대한 원인을 찾지 못하였다.

728x90
반응형

'공부 > 딥러닝' 카테고리의 다른 글

흉부 X-ray 사진으로 폐렴 진단 모델  (0) 2021.05.09
CIFAR-10 의 레이블중 하나를 예측  (0) 2021.05.09
딥러닝 4  (0) 2020.10.29
딥러닝 3  (0) 2020.10.09
딥러닝 2  (0) 2020.09.29
블로그 이미지

아상관없어

,
반응형

간단한 android game app

 

Mono Runtime 가상머신에서 사용하는 중간 언어인 CIL이 있는 dll파일들을 디컴파일하였다.

Assembly-CSharp.dll 파일이 C# 개발자 코드의 컴파일 결과이므로 dnSpy 프로그램을 사용하여 Assembly-CSharp.dll을 수정하였다.

먼저 CompleteProject 파일 안의 정보들을 보고 “Player~~~~” 관련 코드가 플레이어와 관련된 코드라 추측을 하였다. 그리고 각각 “Movement”, “Shooting”, “ScoreManager” 코드에서 변수 이름으로 관련 변수들이 의미하는 것을 추측하였다.

그 후 해당 변수에 들어가 있는 값들을 수정해 주었으나, 실제 게임 구동 시 적용이 되질 않았다.

ctrl+shift+R 키를 통하여 해당 변수가 사용되는 함수들을 찾아보고 해당 함수안에서 변수에 곱을 하여 값을 조작하여 Damage, Speed, Score, Heath를 조절하였다.

 

- Damage 조절

 

- Speed 조절

 

- startHealth 조절

- Score 조절

 

실행 결과

 

[방어 방법]

이러한 해킹을 막기위해선 ProGuardDexGuard와 같은 소스코드 난독화 도구를 사용하여 소스코드를 난독화한다. Renaming(클래스 및 메소드 이름 변경), Control Flow(제어 흐름 변환), String Encryption(문자열 암호화), API Hiding(API 은닉), Class Encryption(파일 내용 전체를 암호화하였다가 동적으로 복호화), Dex Encription(Dalvik Executable 파일 암호화)같은 기법을 사용하여 APK파일을 디컴파일하더라도 코드를 읽기 난해하게하여 공격을 어렵게 만든다.

 

원본 apk파일의 해쉬값을 서버에 저장하여 설치된 apk의 해쉬값과 비교하여 동일한지 판단하여 유효성을 체크한다.

앱에 서명을 하여 원본 서명과 설치된 앱 간의 서명을 비교하여 위변조한 앱인지 체크한다.

Apk 파일에 META-INFapk 배포시 서명한 내용이 들어가는데 파일을 변조할 경우 패키지 손상오류가 뜨며 기기에 설치되지 않는다. apk파일을 리패키징할 때 서명을 해주지 않아 설치가 되지 않는다.

에뮬레이터의 경우 root권한이 설정되어 있어 이를 우회하는 것으로 생각하였으나, root권한을 끈 경우에도 설치가 되는 것으로 보아 에뮬레이터는 앱의 서명을 확인하지 않는 것으로 생각된다.

 

인터넷 검색을 통하여 앱 서명이 이루어지지않은 앱을 구하여 테스트를 해보았다.

서명을 하지 않은 앱들은 실기기(galaxy note5 Android 7.0)에서 패키지가 손상된 것 같습니다라는 에러가 뜨면서 설치가 되지 않는다.

 

반면 LD player의 경우 두 앱이 잘 설치가 된다.

따라서 LD player의 경우 앱 서명 체크를 하지않아 설치가 된다고 생각을 하였다.

728x90
반응형
블로그 이미지

아상관없어

,
반응형

[프로그램 동작]

retlib.c

Badfile을 읽어서 bof의 인자로 전달해준다. Bof 함수는 badfile을 읽고 buffer에 쓰는데 경계체크를 하지 않으므로, 버퍼의 크기를 초과해서 쓰게 된다.

이 곳이 retlib파일의 취약점이 된다.

따라서 버퍼 오버플로우를 일으켜 bof함수의 리턴주소를 system함수로 조작할 수 있게 된다.

 

exploit.c

Exploitbadfile을 열고 buf를 쓴다. Retlibbuffer over flow 취약점을 이용하므로, retlibbof 함수의 return 주소에 system 함수의 주소를 넣고, 인자로 “/bin/sh”을 준다.

그리고 return 주소로 exit를 준다. 따라서 bof함수가 정상적으로 return 되지 않고 system 함수를 호출하고 인자로 “/bin/sh”을 넘겨주어 shell이 실행되게 된다.

RetlibsetUID가 설정되어있고, Non-executable stack이므로 code reuse 공격을 사용하여 libcsystem함수를 이용하여 /bin/shroot권한으로 실행한다.

 

 

Retlib.c bof함수를 disassemble하여 보면 버퍼 위로 더미데이터가 8바이트가 있는 것을 알 수 있고, 따라서 bof함수의 리턴주소의 위치는 buffer[24]임을 알 수 있다.

따라서 리턴 주소를 조작할 수 있게 된다.

그리고 fread하기전 인자들을 전달하는 것을 볼 수 있다.

[ebp+0x8] =badfile의 주소, 0x12c = 300, 0x1 = sizeof(char), [ebp-0x14] = buffer의 시작주소를 전달하는 것을 볼 수 있다.

buffer[24]의 위치는 원래 return address이므로 여기에 system의 주소를 넣고 그 위(buffer[28]) exit의 주소, 그 위(buffer[32]) /bin/sh의 주소를 넣어준다.

 

gdb에서 printfind 함수를 이용해 system함수의 위치는 0xb7e42da0, exit 함수의 위치는 0xb7e369d0, “/bin/sh”의 위치는 0xb7f6382b임을 알 수 있다. 따라서 다음과 같이 exploit.c를 작성하였다.

 

Exploit을 실행하고 retlib을 실행하면 스택이 다음과 같이 바뀌게 된다.

Bof의 리턴주소 = system함수의 주소 -> system함수 호출

Bof 리턴주소 위 4byte = exit 함수의 주소 -> 호출된 system 함수의 리턴 주소가 된다.

Bof 리턴주소 위 8byte = /bin/sh의 주소 -> 호출된 system 함수의 인자로 들어가게된다.

 

retlibbof에서 오버플로우가 발생하고 위와 같이 덮여 쓰여지게 된다.

Non executable stack이라 하더라도 executable code region system함수를 불러오므로 shell을 실행할 수 있게 된다.

이 파일은 setuid bit가 설정되어있고 ownerroot이므로 root의 권한으로 실행되게 된다.

따라서 ruidseed이지만 euid root임을 알 수 있다.

 

[취약점 보완]

컴파일러 수준에서 스택 쉴드를 사용한다. Shadow 스택을 사용하여 함수가 리턴될 때 call stack, shadow stack을 비교하여 일치하지 않을 경우 종료하게 한다.

 

- ASLR을 이용하여 주소를 랜덤화 한다.

 

- 스택 가드기법(-fstack-protector)를 사용하여 스택 변수와 스택 프레임 포인터 사이에 보호값을 넣는다.

 

- 프로그래머가 명시적으로 복사할 크기를 지정해주어 버퍼 오버 플로우가 일어나지 않게 한다.

fread(buffer, sizeof(char), 12, badfile)을 하여 12바이트만 읽어오게 한다.

또는 버퍼의 크기를 badfile의 크기보다 크게 설정해준다.

 

- 코드로 리턴주소와 버퍼 사이에 guard를 설정하여 값이 변경되었는지 확인한다.

이 방법은 공격을 막을 순 있으나, bof 스택 내의 버퍼와 리턴주소 사이를 건드려야하므로, 정상적으로 “Returned Properly”를 출력하지 않고 프로그램이 종료된다.

 

- DashsetUID 프로세스 내에서 권한이 내려가듯 위험한 코드가 실행되기전 권한을 낮추어 버린다.

이 방법도 공격을 막을 순 있으나 bof 함수를 실행을 막지는 못하므로 정상작동하진 않는다.

728x90
반응형
블로그 이미지

아상관없어

,
반응형

[프로그램 동작]

Exploit.c에서 badfilebuffer를 쓴다. 그리고 stack.c에서 badfile를 열고 str에 읽는다. Badfile의 값이 써진 strbof의 인자로 넘겨준다.

Stack.c에서 bof 함수는 인자로 받은 strbuffer에 복사한다. 하지만 strcpyNULL을 만나기 전까지의 문자열을 복사하고 복사할 문자열의 길이는 검사하지 않는다. 따라서 buffer의 크기가 24이고, str의 길이는 517이므로 buffer의 스택을 넘어선다.

이때 bof 함수의 return addressshellcode의 주소를 넣어 shellcode가 실행되게 한다.

 

Gdb를 통해 strcpy가 실행되는 곳에 break를 하였고, bof함수를 disas하여 strcpy0x20크기의 buffer인자가 전달되는 것을 알 수 있다.

따라서 buffer의 크기는 32byte임을 알 수 있다.

 

gdb를 통하여 ebp0xbfffeab8임을 알 수 있고, ebp의 주소에서 0x20만큼 빼주어 buffer의 시작 위치를 알 수 있다. 그리고 이를 토대로 bof return address가 실제와 일치하는지 disas main을 하여 비교를 하면 0x08048574로 같음을 알 수 있다.

 

Buffer의 크기는 32이고 saved edp for bof의 크기는 4이므로 buffer[36]부터가 return address of bof임을 알 수 있다. Exploit.c에서 “memcpy(buffer+sizeof(buffer)-sizeof(shellcode), shellcode, sizeof(shellcode));”를 하여, buffer의 맨 끝에 shellcode를 넣었다.

따라서 정확한 shellcode의 주소를 몰라도 return address 이후와 buffer 이전의 아무 주소 값이나 return address of bof에 넣어준다면 shellcodebuffer의 맨 끝에 있으므로 실행이 될 것이다.

시스템이 Little endian이므로

주소값을 반대로 넣어준다. Buffer의 크기는 32byte이고 saved ebp or bof 4byte이므로 *(buffer +36)return address를 가리키므로, *(buffer +36)부터 차례로 주소를 넣어준다.

이것을 실행하면 원하는 shellcode가 동작하는 것을 볼 수 있다.

 

 

[취약점 메모리 구조]

Bof 함수의 strcpy(buffer, str)이 취약점이다. 먼저 bof 함수 인자인 str이 쌓이고 그 다음에 Return Address of bof, Saved ebp of bof, buffer가 쌓인다. Buffer32byte이고 saved ebp of bof4byte, return address of bof 4byte, str 517bye이다.

Str의 크기가 buffer보다 크고, strcpy는 문자열의 길이를 체크하지 않으므로 str의 값들이 buffer스택 위로 덮어쓰여진다.

 

- Exploit 실행 후 메모리 구조

Exploit이 실행되면, overflow로 인하여 bofreturn address0xbfffeb68(return address 위의 랜덤주소, buffer의 마지막에 shellcode가 있다)이 들어간다.

그리고 NOP 명령어가 실행되다가 buffer의 끝에 있는 shellcode를 실행한다.

 

[취약점 보완]

프로그래머가 스택의 다른 영역을 침범하지 않게 코드상으로 영역을 명확히 명시하거나 입력 받는 데이터의 크기를 확인하거나 buffer overflow에 취약한 함수를 사용하지 못하게 한다.

 Buffer overflow에 취약하지 않은 함수를 사용한다. Strcpy(buffer, str)strncpy(buffer, str, sizeof(buffer)-1)함수로 대체 사용하여 복사할 크기를 지정하여 overflow가 생기지 않도록 한다.

 

 

Strncpy를 사용하여 복사할 크기를 지정해주었을 때 공격이 실패하고 정상적으로 “Returned Properly”가 수행되는 것을 알 수 있다.

또는 sizeof(buffer)BUF_SIZE이나 24로 명확하게 적어준다.

 

인자로 받는 데이터의 크기를 체크한다. bof함수의 인자로 int size값을 받아 str의 크기를 체크하여 오버플로우를 방지한다. Bof(char*str, int size)의 형태로 받는다.

크기가 buffer보다 클 때 warning을 출력하고 exit한다.

 

 

스택 쉴드 기법을 사용하여 함수가 호출될 때 그 함수의 Return Address를 특수 스택에 저장을 하고 함수 종료 시 저장해둔 Return Addresss와 비교를 하여 값이 다르면 프로그램을 종료시킨다.

 

해제한 ASLR(Address Space Layout Randomize)기법을 다시 사용하여 각 프로세스 안의 스택이 임의의 주소에 위치하도록 한다.

해제한 NX bit를 활성화하여 스택/힙 영역의 실행권한을 제거하여 쉘의 실행을 방지한다.

해제한 Stack Guard기법을 사용하여 스택에 Canary 값을 넣고 이 값이 변조되었는지 검사하여 오버플로우를 체크한다.

728x90
반응형

'공부 > 보안' 카테고리의 다른 글

간단한 Android game app hacking  (0) 2021.05.03
SEED Lab Return-to-Libc Attack  (0) 2021.05.03
SystemProperties로 에뮬레이터 탐지  (0) 2021.05.03
BOF 원정대 level 16  (0) 2021.05.03
BOF 원정대 level 18  (0) 2021.05.03
블로그 이미지

아상관없어

,
반응형

LDplayer와 여러 디바이스의 property를 비교하여 차이점을 찾으려 하였다.

하지만 각 스마트폰 제조사, 모델에 따라 각기 다른 property명과 값을 가지고 있어 범용적으로 기기가 real device인지 emulator인지 구분하기 힘들었다.

또한 확실히 구분되는 아키텍쳐 정보는 x86기반의 안드로이드 기기가 나오면서 이것으로 구분하기는 힘들었다. 따라서 실제 가진 기기의 property정보를 바탕으로 emulator와 비교하여 galaxy note 3LDplayer를 구분했다.

아래 사진을 보면 real device에서는 가지는 property이지만 emulator에선 가지지 않는 property를 정리하였다. 그리고 각 기기별로 그 이름이 다 다른 것을 알 수 있다.

(각 테스트 기기는 galaxy S10, galaxy S9, galaxy Note 3, Xperia Z3 Compact 이다.)

(getprop한 정보를 word에 옮겨 비교하였다.)

[Bluetooth 관련 property]

[GPS 관련 property]

[Camera 관련 property]

 

따라서 위와 같이 공통적이지 않은 property emulator인지 구분할 경우 모든 기기의 property를 다 알고 있지 않은 이상 적용하기 어려워 테스트 기기 한정으로 적용을 시켜 테스트하였다.

(위 프로퍼티를 갖고 있지 않은 다른 디바이스에선 emulator라고 탐지하게 된다.)

boolean isProbablyAnEmulator(){ // checking Emulator
    return get("service.camera.running").equals("") && get("ro.bluetooth.tty").equals("");
}

 

 

property외에 usim 관련, 네트워크 관련 property들은 공통적인 이름을 가지고 있으면서 다른 값을 가지는 것을 확인하였다.

[gsm.sim.state]: [NOT_READY] - LDplayer

[gsm.sim.state]: [LOADED] – s10

[gsm.sim.state]: [LOADED] – s9

[gsm.sim.state]: [READY] – note 3

[gsm.sim.state]: [ABSENT] – Xperia z3 compact

컴퓨터 A

컴퓨터 B

Galaxy Note 3

[dhcp.eth0.gateway]: [172.16.2.2]

[dhcp.eth0.ipaddress]: [172.16.2.15]

[dhcp.eth0.leasetime]: [86400]

[dhcp.eth0.mask]: [255.255.255.0]

[dhcp.eth0.mtu]: []

[dhcp.eth0.pid]: [1735]

[dhcp.eth0.reason]: [REBOOT]

[dhcp.eth0.result]: [failed]

[dhcp.eth0.server]: [172.16.2.2]

 

[dhcp.eth0.gateway]: [172.16.2.2]

[dhcp.eth0.ipaddress]: [172.16.2.15]

[dhcp.eth0.leasetime]: [86400]

[dhcp.eth0.mask]: [255.255.255.0]

[dhcp.eth0.mtu]: []

[dhcp.eth0.pid]: [1689]

[dhcp.eth0.reason]: [REBOOT]

[dhcp.eth0.result]: [failed]

[dhcp.eth0.server]: [172.16.2.2]

 

[dhcp.wlan0.gateway]: [192.168.0.1]

[dhcp.wlan0.ipaddress]: [192.168.0.18]

[dhcp.wlan0.leasetime]: [7200]

[dhcp.wlan0.mask]: [255.255.255.0]

[dhcp.wlan0.mtu]: []

[dhcp.wlan0.pid]: [25465]

 

Real Device는 대부분 무선 인터넷환경(wlan)을 이용하니 이 부분을 확인하면 좀 더 쉽게 emulator를 탐지할 수 있을 거라 생각한다. 그리고 LDplayer의 경우 eth0을 사용하고, 다른 컴퓨터 환경에서도 같은 gateway, ipaddress를 가지는 등 이 정보를 가지고도 판단할 수 있을 거라 생각한다.

 

하지만 해당 정보들 모두 최신 emulator에서 값을 조정할 수 있기 때문에, 완벽한 방법은 아니다. 

 

 

 

 


(adb shell getprop를 하였을 때 수업시간에 배운 selinux가 실제 안드로이드 디바이스에 적용이 되있음을 알 수 있었다.)

728x90
반응형
블로그 이미지

아상관없어

,
반응형

0x28 = 40바이트를 할당하므로 dummy는 없음을 알 수 있다.

Main 함수의 에필로그를 보면 위 그림과 같이 동작하는 것을 알 수 있다.

Mov esp, ebp => espebp로 옮긴다.

Pop ebp => esp가 가리키는 값을 ebp에 저장하고 esp를 증가

Pop eip => esp가 가리키는 값을 eip에 저장

Jmp eip =>eip 주소로 이동

Jmp eip에서 system함수로 이동을 하게 하면 되지만, ret 위의 값이 조작이 불가하므로 esp가 조작된 ebp를 가리키게 해야한다.

따라서 리턴주소를 에필로그로 하면 esp가 조작된 ebp를 가리키게 할 수 있다.

 

Strncpybuffer를 채우므로, 먼저 조작된 ebp buffer를 가리키게 한다. 그 다음 리턴 주소를 에필로그로 바꾼다. 그러면 다시 에필로그를 실행하므로 Mov esp, ebp를 한다.

따라서 espbuffer를 가리키게 된다.

Pop ebp-> Pop eip-> Jmp eip를 하므로, 버퍼를 위 그림과 같이 리턴 주소에 system함수의 주소를 넣고, 그 위에 system함수의 리턴주소, 그 위에 인자를 넣어주고 남은 공간은 더미로 채운다.

에필로그 = 0x80484df

System = 0x40058ae0

 

“/bin/sh” => 0x400fbff9

Buffer = 0xbffffab0

 

에필로그 = 0x80484df => 08 04 84 df

System = 0x40058ae0 => 40 05 8a e0

“/bin/sh” => 0x400fbff9 =>40 0f bf f9

Buffer = 0xbffffab0 => bf ff fa b0

 

$(python -c 'print "A"*4 + "\xe0\x8a\x05\x40" + "A"*4 + "\xf9\xbf\x0f\x40" + "\x90"*24 + "\xb0\xfa\xff\xbf" + "\xdf\x84\x04\x08"')

 

실행 후

0xbffffaa0에 들어간 것을 알 수 있었다.

따라서 buffer주소를 바꾸어 주었다.

Bf ff fa a0

$(python -c 'print "A"*4 + "\xe0\x8a\x05\x40" + "A"*4 + "\xf9\xbf\x0f\x40" + "\x90"*24 + "\xa0\xfa\xff\xbf" + "\xdf\x84\x04\x08"')

(PuTTY가 출력되는 이유는 모르겠다, zombie_assassin  gdb하였을때, Operation not permitted가 발생하여 cp하여 소유자가 assassin zombie_assassi2파일을 사용하였다. )

728x90
반응형
블로그 이미지

아상관없어

,
반응형

코드에서 먼저 memcmp을 하여 argv[1] + 44 위치에 strcpy의 주소가 있는지 체크를 한다.

그리고 strcpy(buffer, argv[1])을 하여 argv[1]buffer로 복사한다.

 

그 다음 memset(buffer+40+8, ‘A’, 4)를 하여 buffer ret위를 “AAAA”로 채운다..

Argv[1] + 44 위치에 strcpy 주소를 넣으므로, 메인함수의 retstrcpy가 되게된다.

“AAAA”가 저장된 곳이 strcpyret이고, 그 위 4byte strcpy함수의 destination, 그 위 4bytesource가 된다.

source system 함수의 주소를 넣고, destination“AAAA”(strcpy ret) 주소를 넣으면 strcpyretsystem함수가 된다.

그리고 system함수의 인자를 주기 위해 buffersystem함수주소(4) + ret(더미) + “/bin/sh”주소(system함수의 인자)를 채우고 buffer 주소를 source에 넘기면 system함수의 인자도 동시에 줄 수 있다.

Sub $0x2c, %esp => 44byte를 할당하므로 buffer위에 더미 값은 할당되지 않는다.

 

P strcpy, p system으로 각 주소를 얻는다.

Strcpy = 0x8048410, system = 0x40058ae0

 

“/bin/sh”의 주소를 얻는 코드를 작성하여 주소 값을 얻는다.

/bin/sh =>0x400fbff9

 

혹은

 

환경 변수를 추가하여 찾을 수도 있다.

 

 

 

Buffer = 0xbffffaa0

&ret+4 = 0xbffffad4

 

Strcpy = 0x8048410, system = 0x40058ae0, /bin/sh = 0x400fbff9, Buffer = 0xbffffaa0, &ret+4 = 0xbffffad4를 구하였다.

 

따라서 payload를 적으면  $(python -c 'print "\xe0\x8a\x05\x40" + "A"*4 + "\xf9\xbf\x0f\x40" + "\x90"*32 + "\x10\x84\x04\x08" + "A"*4 + "\xd4\xfa\xff\xbf" + "\xa0\xfa\xff\xbf"')가 된다.

실행 결과

Segmentation fault가 나와 명령어를 다시 살펴보았다.

예상한 값이 들어가지 않은 것을 알 수 있었다.

/bin/sh 뒤에 NOP명령어를 32바이트 주었는데 중간에 이상한 값이 들어가 있었습니다. 이 원인을 찾고자 하였다.

 

Breakmemset 이후로 걸고 주소값을 찾았다.

 

buffer => 0x bf ff fa b0 (그림 잘못표기함)

Ret+4 -> 0x bf ff fa e4

$(python -c 'print "\xe0\x8a\x05\x40" + "A"*4 + "\xf9\xbf\x0f\x40" + "\x90"*32 + "\x10\x84\x04\x08" + "A"*4 + "\xe4\xfa\xff\xbf" + "\xb0\xfa\xff\xbf"')

Buffer의 시작 주소를 0xbffffaa0

Ret + 4 주소를 0xbffffad4로 바꾸어 실행해보았습니다

 

하지만 작동하지 않았다.

 

하지만 여전히 원인을 찾지 못하여 이때까지 실행한 결과를 적는다...

 

 

추가로 LOB Redhatbash의 버전이 낮아서 \xff\x00으로 처리하므로

Bash2로 변경하였다.

728x90
반응형

'공부 > 보안' 카테고리의 다른 글

SystemProperties로 에뮬레이터 탐지  (0) 2021.05.03
BOF 원정대 level 16  (0) 2021.05.03
간단한 버퍼 오버플로우  (0) 2021.04.28
Data type, Array operations, Byte ordering  (0) 2021.04.28
MyEtherWallet 해킹사건 분석  (0) 2021.04.18
블로그 이미지

아상관없어

,
반응형

오픈소스 프로젝트

사용자 인터페이스를 만드는 리액트에 기반을 두고 제작

ios/Android에서 동작하는 네이티브 모바일 앱을 만드는 자바스크립트 프레임워크

 

장점

- 코드 대부분이 플랫폼(ios/android)간 공유가능

- 패스트 리프레쉬로 변경된 코드를 저장하기만 해도 확인가능

 

단점

- 네이티브의 새로운 기능을 사용하는데 오래 걸림

- 유지보수 어려움

- 잦은 업데이트

 

리액트 네이티브 CLI를 이용하여 리액트 네이티브 프로젝트 생성

npx react-native init 프로젝트이름 --version x.xx.x

 

npx react-native init MyFirstCLI

cd MyFirstCLI

npm run android or npx react-native run-android

 

리액트 네이티브가 실행되면서 Metro가 실행된다.

Metro는 리액트 네이티브가 실행될 때마다 자바스크립트 파일들을 단일 파일로 컴파일 하는 역할을 한다.

 

npm run android 시 gradle 에러가 나는데 jdk16버전에서 jdk14버전으로 바꾸니 해결되었다.

따라서 정상적으로 실행되면 다음과 같다

 

 

 

 

 

MyFirstCLI 폴더에 src 폴더를 생성 후 App.js파일을 생성한다.

./src/App.js

import React from 'react'
import {View, StyleSheet, Text} from 'react-native';
const App = () => {
    return(
        <View style={styles.container}>
            <Text style={styles.title}>My First React Native</Text>
        </View>
    );
};

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backfroundColor: '#ffffff',
    },
    title: {
        fontsize: 30,
    },
});

export default App;

 

./App.js 를 다음과 같이 바꾼다.

import App from './src/App';

export default App;

./index.js

import {AppRegistry} from 'react-native';
import App from './src/App';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);

 

첫 화면을 구성하는 파일만 변경하고 리액트 네이티브에서 사용되는 파일을 모두 src 폴더에서 관리하도록 한다.

 

728x90
반응형
블로그 이미지

아상관없어

,
반응형

카멜케이스

- CamelCase

 

lower 카멜케이스

- camelCase

 

스네이크케이스

- snake_case

 

파스칼케이스

- PascalCase

728x90
반응형
블로그 이미지

아상관없어

,
반응형

var / let

var은 

var a = 'a'

var a= 'b'

가 가능하므로 let을 사용

let은 한번 선언하면 재선언불가하고 재할당 가능하다.

 

== / ===

==은 자동으로 타입변환을 하여 값을 비교하지만

===은 타입변환을 하지않고 값을 비교한다. 따라서 값과 타입이 같아야한다.

 

for in / for of

for in은 객체에 사용(객체 프로퍼티 접근) => ex) foo = { name : 'foo' ~~~~}

for of는  iterable한(반복되는) 객체에 사용, 주로 값을 찾을 때 사용(원소에 접근) => foo = [1, 2, 3 ~~]

 

함수 표현식

함수 리터럴로 하나의 함수를 만들고 생성된 함수를 변수에 할당함

//함수 이름 사용
fuction add(x,y){
	return x+y
}
add(3,4)



//익명함수 사용 => 위와같이 함수 이름이 없다
const add = function(x,y){
	return x+y
}

add(3, 4)

 

기본인자

const print = fucntion ( defaultVal = 'default'){
	console.log(defaultVal)
}

 

함수 호이스팅

//호이스팅

add(3, 4) //=>undefined
function add (x, y){
	return x+y
}

add(3, 4) // 에러
const add = function (x, y){
	return x+y
}

console.log(add)//undefined => add 선언 전 undefined로 초기화
add(3, 4)// 에러 add는 함수가 아님
var add = function (x, y){
	return x+y
}

함수를 const 변수에 할당하여 변수처럼 취급

 

Arrow function => 함수 간단히

const nothing = function (x){
	return x
}

console.log(nothing(1))

//fucntion 삭제 가능
const nothing1 = (x) =>{
	return x
}
console.log(nothing1(1))

//괄호 삭제가능 매개변수가 한개일 경우
const nothing2 = x =>{
	return x
}
console.log(nothing2(1))

//중괄호, return 삭제가능 함수 안 표현식이 1개인 경우만
const nothing3 = x => x
console.log(nothing3(1))

 

 

배열관련 메소드

reverse => 배열 원소 반대로 정렬

push => 맨끝에 원소 추가

pop => 맨끝 원소 삭제

unshift => 맨 앞에 원소 추가

shift => 맨 앞 원소 삭제

include(val) => 배열이 val을 가지고 있는지 판단 (참/거짓)

indexOf(val) => val이 존재하면 첫번째로 찾은 val의 인덱스값 반환, 없으면 -1 반환

const num = [1, 1, 3, 1, 3]

num.indexOf(3) => 2반환

join(구분자) => 기본(join())은 "," 

const test = [1, 2, 3]

console.log(test.join("+"))
console.log(test.join("-"))
console.log(test.join(","))
console.log(test.join(" and "))

 

*callback 함수

익명함수의 대표적인 예시

함수를 등록하기만 하고 이벤트가 발생하거나 특정 시점에 도달했을 때 시스템에서 호출되는 함수

or

함수의 인자로 넘겨서 코드 내부에서 호출되는 함수

 

 

forEach

const arr = [1, 2, 3, 4, 5]

arr.forEach((element, index, array) => {
    console.log('elemnet :'+ element)
    console.log('index :'+index)
    console.log(array)
})

===========================================
elemnet :1
index :0
[ 1, 2, 3, 4, 5 ]
=>[ 1, 2, 3, 4, 5 ]배열에서 원소 1의 index는 0

elemnet :2
index :1
[ 1, 2, 3, 4, 5 ]
=>[ 1, 2, 3, 4, 5 ]배열에서 원소 2의 index는 1

elemnet :3
index :2
[ 1, 2, 3, 4, 5 ]
=>[ 1, 2, 3, 4, 5 ]배열에서 원소 3의 index는 2

elemnet :4
index :3
[ 1, 2, 3, 4, 5 ]
=>[ 1, 2, 3, 4, 5 ]배열에서 원소 4의 index는 3

elemnet :5
index :4
[ 1, 2, 3, 4, 5 ]
=>[ 1, 2, 3, 4, 5 ]배열에서 원소 5의 index는 4

 

 

map => 기존 배열을 새 배열로 만들 때 사용(기존 배열이 변하지 않음)

array.map(callbackFunction(element, index, array), thisArg)

thisArg = callback함수 내에서 this로 사용될 값

const arr = [1, 2, 3, 4, 5]

const returnArr = arr.map((element, index, array) => {
		console.log(element)
        console.log(index)
        console.log(array)
        return element*2;
    })
    
 console.log(returnArr)
 
 =========================
1
0
[ 1, 2, 3, 4, 5 ]

2
1
[ 1, 2, 3, 4, 5 ]

3
2
[ 1, 2, 3, 4, 5 ]

4
3
[ 1, 2, 3, 4, 5 ]

5
4
[ 1, 2, 3, 4, 5 ]


[ 2, 4, 6, 8, 10 ]

 

 

filter

콜백 함수의 반환값이 참인 값만 반환 => 필터링

const num = [10, 20, 30, 40, 50]

const result = num.filter((num)=>{
	return num>=30
})

console.log(result)

=> [30, 40, 50]

=>결과가 true를 반환한 원소들로만 배열을 만든다.

find는 요소를 반환

 

reduce => 콜백 함수의 반환값 acc에 누적

reduce(function(acc, currentValue, currentIndex, array){ , initialValue);

acc = 콜백의 반환값 누적

currentValue = 현재 처리할 요소 (옵션)

currentIndex = 현재 처리할 요소 인덱스 (옵션)

array = reduce() 호출할 배열 (옵션)

initialValue = 초기값 (옵션 => 초기값이 없으면 배열의 첫번째 요소 사용)

//콜백 함수 이용시 밑의 function처럼 콜백함수 이름을 적어도 되고 안적어도됨
const result = [0, 1, 2, 3, 4].reduce(function(acc, currentValue, currentIndex, array){
    console.log(`currentIndex : ${currentIndex}`);
    console.log(`currentValue : ${currentValue}`);
    console.log(`currentIndex : ${currentIndex}`);
    console.log(`acc : ${acc}`);
    return acc + currentValue;
}, 0); //acc의 초기값은 0

console.log("result:", result);

==========================
currentIndex : 0
currentValue : 0
currentIndex : 0
acc : 0

currentIndex : 1
currentValue : 1
currentIndex : 1
acc : 0

currentIndex : 2
currentValue : 2
currentIndex : 2
acc : 1

currentIndex : 3
currentValue : 3
currentIndex : 3
acc : 3

currentIndex : 4
currentValue : 4
currentIndex : 4
acc : 6

result: 10

 

find => callback 함수에 정의한 조건에 맞는 배열의 첫번째 요소를 리턴 (없으면 undefined)

find(callback(element, index, array)

const arr = [
  {name: 'a', age : 10}, 
  {name: 'b', age : 20},
  {name: 'c', age: 30}
];

const result = arr.find((arr) => {
	return arr.name == 'a'
})

console.log(result)

=>{ name: 'a', age: 10 }

 

 

some => callback함수에서 true를 리턴하면 true 리턴, 하나라도 참이면 참 반환

array.some(callback(currentValue, index, array), thisArg)

const num = [10,20,25,40,50]

const overThrity = num.some((val) => {
	return val>30
 })
 console.log(overThrity)
 
 
 const underThrity = num.some((val) => {
	return val<30
 })
  console.log(underThrity)
  
   const overFifty = num.some((val) => {
	return val>50
 })
   console.log(overFifty)
   
   
===========
true
true
false

 

 

every => callback함수에서 모든 요소가 참이면 참

const num = [10,20,25,40,50]

const overThrity = num.every((val) => {
	return val>30
 })
 console.log(overThrity)
 
 
 const underThrity = num.every((val) => {
	return val<30
 })
  console.log(underThrity)
  
   const underFifty = num.every((val) => {
	return val<=50
 })
   console.log(underFifty)
   
 ========
false
false
true

 

728x90
반응형
블로그 이미지

아상관없어

,
반응형

- 자바스크립트에서의 배열은 크기를 지정하지 않아도 된다.

- 어떤 위치에 어느 타입의 데이터를 저장하더라도 에러가 발생하지 않는다.

 

 

배열 리터럴

- 자바스크립트에서 새로운 배열을 만드는 데 사용하는 표기법이다.

- [] 대괄호를 사용한다.

var Arr = ['a', 'b', 'c', 'd', 'e'];

 

동적으로 배열원소를 추가할 수 있다.

var Arr = [];

Arr[0] = 100;
Arr[5] = 'a';
Arr[10] = true;

console.log(Arr.length); // 10

값을 순차적으로 넣을 필요 없이 아무 인덱스 위치에 값을 추가할 수 있다.

배열의 크기는 인덱스 중 가장 큰값을 기준으로 정해진다.

(모든 배열은 length 프로퍼티를 가진다.)

 

*length 프로퍼티

length 프로퍼티는 명시적으로 값을 변경할 수 도 있다.

var arr = [0, 1, 2];

console.log(arr.length); // 3

arr.length = 6;
console.log(arr.length); // 6
//[0, 1, 2, undefined, undefined, undefined]

arr.length = 2; // arr[2]인 2값은 삭제된다.
console.log(arr); // 0, 1
console.log(arr[2]); // undefined

push()메소드를 통하여 새로운 원소값을 추가할 수 있다.

(배열의 크기도 늘어난다.)

 

배열과 객체의 차이점

var arr = ['a', 'b', 'c'];

console.log(arr[0]);
console.log(arr[1]);
console.log(arr[2]);
//a, b, c


var obj = {
		'0' : 'a',
        '1' : 'b',
        '2' : 'c'
};
// => 프로퍼티 속성 이름이 '0', '1', '2'이다.

console.log(obj[0]); //=> 자동으로 toString으로 변환되어 obj['0']으로 인식한다.
console.log(obj[1]);
console.log(obj[2]);
//a, b, c


//typeof로 비교 => 둘다 objcet이다.
console.log(typeof arr); // object (not array)
console.log(typeof obj); // object

//length=> 객체는 length 프로퍼티가 없다.
console.log(arr.length); // 3
console.log(obj.length); // undefined

//push => 객체는 배열이 아니므로 표준 배열 메소드를 사용할 수 없다.
// 객체 리터럴 방식으로 생성한 객체는 Object.prototype 객체가 프로토타입이므로
arr.push('d'); //['a', 'b', 'c', 'd']
obj.push('d'); // Uncaught TypeError : Object #<Object> has no method 'push'

 

객체 -> Object.prototype

배열 -> Array

728x90
반응형

'공부 > 리액트 네이티브' 카테고리의 다른 글

리액트 네이티브 - jsx  (0) 2021.05.06
리액트 네이티브  (0) 2021.05.02
자바스크립트 - 정리  (0) 2021.04.30
자바스크립트 - 참조타입(객체) 1  (0) 2021.04.30
자바스크립트 - 기본타입  (0) 2021.04.30
블로그 이미지

아상관없어

,
반응형

자바스크립트에서 기본타입을 제외한 모든 값은 객체이다.

배열, 함수, 정규표현식 등도 모두 객체로 표현된다.

객체는 참조타입이라고 불림 => 객체의 모든 연산이 실제 값이 아닌 참조값으로 처리되기 때문

 

객체 생성

- 자바스크립트는 클래스 개념이 없다.

- 객체 리터럴이나 생성자 함수 등 별도의 생성 방식을 사용함

1. Object() 객체 생성자 함수 이용

//foo 빈 객체 생성
var foo = new Object(); 


//foo 객체 프로퍼티 생성
foo.name = 'foo';
foo.age = 30;
foo.gender = 'male';


console.log(typeof foo);
console.log(foo);

//출력
//object
//{name: 'foo', age: 30, gender: 'male'}

 

2. 객체 리터럴 방식 이용

리터럴 = 표기법

객체리터럴 = 객체 생성하는 표기법

{프로퍼티_이름 : 값}를 이용하여 객체 생성

//객체 리터럴 방식으로 객체 생성
var foo={	
	name : 'foo',	
    	age : '30',	
    	gender : 'male'
    };

 

3. 생성자 함수 

함수를 통하여 객체 생성 가능

 

 

객체 프로퍼티 접근

[] 또는 . 표기법으로 접근

//객체 생성
var foo = {
	name : 'foo',
    	major : 'conputer'
};

//읽기
console.log(foo.name); //  foo
console.log(foo['name']); // foo
console.log(foo.nickname); // undefined


//수정
foo.major = 'electronics';
console.log(foo.major); // electronics
console.log(foo['major']); // electronics


//객체 프로퍼티 동적 생성
foo.age=30;
console.log(foo.age); // 30


//대괄호 표기법만 사용해야하는 경우
foo['full-name'] = 'foo bar'; //동적으로 'full-name' 프로퍼티 생성

console.log(foo['full-name']);// foo bar
console.log(foo.full-name); // NaN

console.log(foo.full); // undefined
console.log(name); // undefined



- [] 사용시 접근하려는 프로퍼티 이름을 문자열 형태로 만들어야함

(자바스크립트에서는 대괄호 표기법에서 접근하려는 프로퍼티 이름을 문자열 형태로 만들지 않으면, 모든 자바스크립트 객체에서 호출가능한 toString() 메소드를 호출하여 문자열로 바꿈)

- 대괄호 표기법만 사용해야하는 경우가 있음 => 접근하려는 프로퍼티가 표현식이거나 예약어일 경우

      full-name의 경우 - 연산자가 있는 표현식임

      console.log(foo.full-name); 와 같이 마침표로 표기할경우 Not a Number이라고 표시된다.

      NaN은 수치연산을 해서 정상적인 값을 얻지 못할때 출력된다. ex) 1 - 'hello' (숫자 - 문자열)

      foo.full-name은 (foo.full) - name으로 취급한다.

 

* for in문

var prop;
for (prop in foo){
	console.log(prop, foo[prop]);
}

 

 

객체 프로퍼티 삭제

var foo = {
	name : 'foo',
    nickname : 'babo'
};


console.log(foo.nickname); // babo

delete foo.nickname; // 삭제

console.log(foo.nickname); // undefined


delete foo; // delete는 프로퍼티만 삭제된다.
console.log(foo.name); // foo

 

 

 

참조 타입 특성

var obj1 = {
	val : 40
};

var obj2 = obj1;


console.log(obj1.val); //40
console.log(obj2.val); //40

obj2.val = 50;

console.log(obj1.val); //50
console.log(obj2.val); //50

obj1은 객체를 저장하는 것이 아니라 객체를 가리키는 참조값을 저장한다.

obj2=obj1을 하면 obj2도 obj1이 가리키는 참조값을 가지게 된다.

따라서 obj1,2가 가리키는 객체는 동일한 객체이다.

 

 

객체비교

var a = 100;
var b = 1--;

var obj1 = {value: 100};
var obj2 = {value: 100);
var obj3 = obj2;

console.log(a == b); // true
console.log(obj1 == obj2); // false 다른 객체를 참조하므로
console.log(obj2 == obj3); // true 같은 객체를 참조하므로

 

 

참조에 의한 함수 호출 (call by reference)

var a =100;
var obj = { value: 100};

function changeArg(num, obj){
	num = 200;
    	obj.value = 200;
        
        console.log(num);
        console.log(obj);
}


changeArg(a, obj);// 200 {value: 200}
=> num에 100 값이 전달되고 200으로 바뀜, ojb.value = 200이 됨

console.log(a); //100
console.log(obj);// {value: 200} 참조에 의한 호출이므로

 

 

프로토타입

- 모든 객체는 자신의 부모 역할을 하는 객체와 연결되어 있음

- 객체지향의 상속과 같이 부모 객체의 프로퍼티를 자신의 것처럼 사용할 수 있음

- 부모객체를 프로토타입 객체라고 함

var foo = {
	name: 'foo',
    	age : 30
};

//foo 객체의 toString 메소드 호출 => foo객체의 프로토타입에 toString이 정의되어 있음
foo.toString();

console.dir(foo);

 

크롬에서 실행하게되면 __proto__ 프로퍼티가 있는 것을 알 수 있다.

 

모든 객체는 자신의 부모 역할을 하는 프로토타입 객체를 가리키는 숨겨진 프로퍼티가 있음.

크롬에서는 __proto__가 숨겨진 프로퍼티이다.

 

모든 객체의 프로토타입은 자바스크립트의 룰에 따라 객체를 생성할 때 결정된다. 

객체 리터럴 방식으로 생성된 객체는 Object.prototype 객체가 프로토타입 객체가 된다.

728x90
반응형

'공부 > 리액트 네이티브' 카테고리의 다른 글

리액트 네이티브 - jsx  (0) 2021.05.06
리액트 네이티브  (0) 2021.05.02
자바스크립트 - 정리  (0) 2021.04.30
자바스크립트 - 참조타입(객체) 2(배열)  (0) 2021.04.30
자바스크립트 - 기본타입  (0) 2021.04.30
블로그 이미지

아상관없어

,
반응형

자바스크립트에서 기본 타입은 숫자, 문자열, boolean, null, undefined라는 타입이 있다.

자바스크립트는 변수를 선언할 때 타입을 미리 정하지 않고, var라는 한가지 키워드로만 변수를 선언한다.

 

//예시

//숫자
var intNUM = 1;

//문자열 타입
var Str = 'asdf';
var Str2 = "Asdfasd";
var Char = 'a';

//boolean
var blool = true;

//undefined
var emptyVar;

//null
var nullVar = null;


//타입은 typeof 연산자를 이용하여 확인한다.
typeof intNUM;
..
...

 

숫자

- 자바스크립트는 하나의 숫자형만 존재

- 자바스크립트는 모든 숫자를 64비트 부동 소수점 형태로 저장하기 때문

- 모든 숫자를 실수로 처리하므로 나눗셈 연산시 주의해야함

EX) 5/2를하면 2.5가 나온다

소수점을 버리고 정수부분만 구하고 싶으면 Math.floor(숫자) 메소드 사용 

 

 

문자열

- 작은따옴표나 큰 따옴표로 생성

- 자바스크립트에서는 char타입과 같이 문자 하나만을 별도로 나타내는 데이터 타입은 존재하지 않음

- 한번 정의된 문자열은 변하지 않는다.(한번 생성된 문자열은 읽기만 가능, 수정은 불가)

var str = 'test';
console.log(str[0]. str[1], str[2], str[3]); //=> test

str[0] = 'T';
console.log(str); //=> test로 소문자가 나온다. 
//한번 정의된 문자열은 변하지 않는다.

- 문자열은 문자 배열처럼 인데그슬 이용하여 접근 가능

 

 

boolean

- true, false값 가짐

 

null, undefined

- 값이 비어있음을 나타냄

- 기본적으로 값이 할당되지 않은 변수는 undefined임

- undefined 타입의 변수는 변수 자체값이 undefined임 => undefined가 타입이면서 값이다.

 

- null의 경우는 명시적으로 값이 비어있음을 나타낸다.

- null의 타입은  object로 ==을 사용하여 변수의 값을 확인해야함

typeof nullVar == null (x)
nullVar == null (o)

 

 

 

 

 

 

728x90
반응형
블로그 이미지

아상관없어

,
반응형
#include<stdio.h>

void echo()
{       
        char buf[4]; // small
        gets(buf);
        puts(buf);
}       

int main()
{
        printf("Type a string:");
        echo();
        return 0;
}   

=> gets시 4byte보다 큰 값이 입력되면 버퍼가 넘치게 된다. 따라서 saved ebp, return address에 덮여씌여지게 된다.

만약 abcdef입력시)

728x90
반응형

'공부 > 보안' 카테고리의 다른 글

BOF 원정대 level 16  (0) 2021.05.03
BOF 원정대 level 18  (0) 2021.05.03
Data type, Array operations, Byte ordering  (0) 2021.04.28
MyEtherWallet 해킹사건 분석  (0) 2021.04.18
보안개론 정리(2) - software 취약점  (0) 2021.04.16
블로그 이미지

아상관없어

,
반응형

Basic Data Types

 

- Integral

intel GNU assembler bytes c
byte b 1 [unsigned] char
word w 2 [unsigned] short
double word l 4 [unsigned] int
quad word q 8 (컴퓨터마다 다름 4 or 8) [unsigned] long int (x86-64)

- Floating point

intel GNU assembler bytes c
single s 4 float
double l 8 double
extended t 10/12/16(system, os, complier 마다 다름) long double

배열의 할당

char 배열의 주소 크기는 1 byte

int 배열의 주소 크기는 4byte (한 원소당 4byte를 차지하므로)

double 배열의 주소 크기는 8byte

-포인터 배열

32bit 구조는 address bus가 4byte이므로 주소도 4byte

64bit 구조는 address bus가 8byte가 가능하다. 하지만 8byte는 큰 공간이므로 메모리 낭비라고 생각하여 6byte씩 표현하는 경우도 있다.

 

 

Array operations

예시

int val[5];

1 5 2 1 3

주소 : x -> x+4 ->x+8 ->x+12->x+16

val[4] = 3

val = x

val+1 =x+4

&val[2] = x+8

val[5] = ?

*(val+1) = 5

val +i = x+4i

 

예시1)

#include <stdio.h>
typedef int zip_dig[5];
int main() {
    zip_dig cmu = {1, 5, 2, 1, 3};
    zip_dig mit = {0, 2, 1, 3, 9};
    zip_dig ucb = {9, 4, 7, 2, 0};

    printf("%p \n", cmu);
    printf("%p \n", mit);
    printf("%p \n", ucb);

    /*-----------------------------------*/
    printf(“%d, ”, cmu[8]);
    printf(“%d, ”, cmu[11]);
    printf(“%d, ”, ucb[-5]);
    printf(“%d\n”, ucb[-15]);
}

 

(32bit로 컴파일)

stack protector가 설정되어있으므로 낮은 주소부터 할당이 된다.

연속으로 배열이 할당이되고 낮은 주소부터 할당이 되는 것을 알 수 있다.

0x14 =>20byte 만큼 주소가 차이난다.

 

-fstack-protector을 하면 64->78->8c로 스택이 자라고

-fno-stack-protector을 하면 bc -> a8 -> 94로 낮은주소로 스택이 자란다.

(64bit로 컴파일)

주소체계도 다르고, 0x20만큼 주소가 차이나는 것을 알 수 있다. 32byte만큼 주소차이가 난다.

(오타, 0x7ffe1eadaa40이 아니라50이다....)

 

예시 2)

#include <stdio.h>
typedef int zip_dig[5];
int main() {
    zip_dig cmu = {1, 5, 2, 1, 3};
    zip_dig mit = {0, 2, 1, 3, 9};
    zip_dig ucb = {9, 4, 7, 2, 0};

    printf("%p \n", cmu);
    printf("%p \n", mit);
    printf("%p \n", ucb);

    printf("%d, %d, %d, %d\n",mit[-5], mit[-4], mit[8], mit[9]);
}

 

 

(stack proctector)

=>

0x20만큼 주소가 차이남 (5개의 원소)

 

(no stack protector)

=>

-fno-stack-protector(스택 보호기법 해제) -> 높은위치에서 낮은 위치로 성장

5c -> 48 ->34

 

주소체계와 접근하는 방식이 달라짐!

 

 

(64bit의 경우)

 

(64bit no stack protector)

 

 

 

예시 3)

#include <stdio.h>
typedef int zip_dig[5];
int main() {
    zip_dig cmu = {1, 5, 2, 1, 3};
    zip_dig mit = {0, 2, 1, 3, 9};
    zip_dig ucb = {9, 4, 7, 2, 0};

    printf("%p \n", cmu);
    printf("%p \n", mit);
    printf("%p \n", ucb);

    printf("cmu[8] : %d \n", cmu[8]);
    printf("cmu[12] : %d \n", cmu[12]);
    printf("mit[8] : %d \n", mit[8]);
    printf("mit[-4] : %d \n", mit[-4]);
    printf("ucb[-4] : %d \n", ucb[-4]);
    printf("ucb[-12] : %d \n", ucb[-12]);
    printf("\n");
    printf(" *(cmu+9) : %d \n", *(cmu+9));
    printf(" *(cmu+11) : %d \n", *(cmu+11));
    printf(" *(mit-4) : %d \n", *(mit-4));
    printf(" *(ucb-5) : %d \n", *(ucb-5));


}

 

 

 

 

예시 4)

#include <stdio.h>
void main() {
    int k = 100;

    int a[4] = {0, 1, 2, 3};
    int b[4] = {4, 5, 6, 7};
    int c[4] = {8, 9, 10, 11};

    a[-1] = 0xAA;
    a[7] = 0xBB, a[10] = 0xCC;
    c[-2] = 0xDD, c[-6] = 0xEE;

    printf("k = %d (0x%x)\n", k, k);

    for(int i=0; i<12; i++) {
        printf ("%3d (0x%x) ", a[i], a[i]);
        if ((i+1) % 4 == 0) printf ("\n");
    }

}

=> 인덱스에 음수가 가능

=> 인덱스가 본래 의미한 것보다 더 큰 값도 가능(다른 위치도 배열의 인덱스로 접근가능)

따라서 c는 메모리 관련 취약점이 많음

(64bit)

(64bit stack보호 기법해제)

 

 

Byte ordering

=> 취약점을 분석할때 컴퓨터 구조에 맞는 데이터를 투입해야하므로 알아야함

little endian은 최소 유효 byte가 낮은 주소를 차지한다.

big endian은 최소 유효 byte가 높은 주소를 차지한다.

type별 크기

=> big/little endian에 따라 c[0]이 낮은주소/높은주소 일 수 있다.

728x90
반응형
블로그 이미지

아상관없어

,
반응형

1. 다음과 같은 컬럼을 갖는 테이블 student 를 생성하시오. 자료형은 각자 알아서 한다)

CREATE TABLE student (

sid INT NOT NULL PRIMARY KEY,

sname VARCHAR(10),

major VARCHAR(10),

gender CHAR(1) DEFAULT 'M',

reg_order INT,

lastchg DATETIME );

 

2. 4명의 학생 정보를 입력하시오 (남학생 2명, 여학생 2명)

INSERT INTO student (sid, sname, major, gender, reg_order)

VALUES(32210001, 'student1', 'software', 'M', 1),

(32210002, 'student2', 'software', 'F', 2),

(32210003, 'student3', 'software', 'M', 3),

(32210004, 'student4', 'software', 'F', 4);

 

3. student 테이블에 score (학점) 컬럼을 추가하시오

ALTER TABLE student ADD score INT;

 

4. student 테이블에서 reg_order 를 admit_order 로 변경하시오 => 다시

ALTER TABLE student CHANGE COLUMN reg_order admit_order INT;

ALTER TABLE studnet CHAGE reg_order admit_order INT;

 

 

5. 남학생들의 학점은 2.5 로 여학생들의 학점은 3.0 으로 입력하시오 (두개의 SQL문 필요)

UPDATE student SET socre=2.5 WHERE gender='M';

UPDATE studnet SET score=3.0 WHERE gender='F';

 

7. 근무지가 ‘BOSTON’ 인 사원에게 보너스(comm)를 급여의 50% 수준으로 지급 하도록 입력하시오

UPDATE emp SET comm = sal/2 WHERE deptno=(SELECT deptno FROM dept WHER loc='BOSTON');

 

8. 입사년도가 1980 년도인 사원들의 급여를 5000 씩 올리시오

UPDATE emp SET sal = sal+5000

WHERE YEAR(hirdate) = 1980;

 

4. emp 테이블에서 연봉이 4000 이상인 사람의 사원번호, 이름, 매니저이름, 연봉 데이터를 top_sal.csv 파일에 저장하시오

SELECT e.empno, e.ename, m.ename, e.sal INTO OUTFILE 'C:\\ProgramData\\MySQL\\MySQL Server 8.0\\Uploads\\top_sal.csv'

FIELDS TERMINATED BY ','

LINES TERMINATED BY '\n'

FROM emp e, emp m

WHERE e.sal >= 4000 AND e.mgr=m.empno;

 

5. dept 테이블의 데이터를 dept.csv 파일에 저장하시오

SELECT * INTO OUTFILE 'C:\\ProgramData\\MySQL\\MySQL Server 8.0\\Uploads\\dept.csv'

FIELDS TERMINATED BY ','

LINES TERMINATED BY '\n'

FROM dept;

 

728x90
반응형

'공부 > 데이터베이스' 카테고리의 다른 글

저장 프로시저  (0) 2021.05.15
  (0) 2021.05.15
데이터베이스 예제 3  (0) 2021.04.20
데이터베이스 예제 2  (0) 2021.04.20
데이터베이스 예제 1  (0) 2021.04.19
블로그 이미지

아상관없어

,
반응형

1. DALLAS 에서 근무하는 사원의 이름, 부서명, 담당업무를 보이시오

SELECT ename, dname, job

FROM emp, deptno

WHERE emp.deptno=deptno.deptno AND loc='DALLAS';

 

2. DALLAS 에서 근무하는 사원중 연봉이 4000 이하인 사람은 몇 명인가

SELECT COUNT(*) FROM emp, dept

WHERE emp.deptno=dept.deptno AND loc='DALLAS' AND sal<=4000;

 

3. PRESIDENT (사장)이 근무하는 지역은 어디인가

SELECT loc FROM emp, dept WHERE emp.deptno=dept.deptno AND job='PRESIDENT';

 

4. 모든 매니저의 이름과 부하직원의 이름을 보이시오 (매니저이름으로 정렬하여 보 이시오)

SELECT m.ename, e.ename FROM emp e, emp m

WHERE e.mgr=m.empno 

ORDER BY m.ename;

 

5. 모든 매니저의 이름과 부하직원의 숫자를 보이시오 => 다시

SELECT m.ename, COUNT(*) FROM emp e, emp m

WHERE e.mgr=m.empno

GROUP BY m.ename;

 

 

6. 각 지역별로 근무하는 사원들의 연봉 합계를 보이시오 (지역명, 연봉합계)

SELECT loc, SUM(sal) FROM emp, dept 

WHERE emp.deptno=dept.deptno GROUP BY loc;

 

7. 매니저가 아닌 (부하직원이 없는) 사원들은 몇 명인가? -중첩사용과 미사용 둘다 =>다시 

SELECT COUNT(*) FROM emp e

WHERE e.empno NOT IN (SELECT mgr  FROM emp WHERE mgr IS NOT NULL);

 

SELECT COUNT(empno) - COUNT(distinct mgr) from emp;

(전체 직원수에서 매니저 수를 빼면 매니저가 아닌 직원 수만 남음)

 

8. 매니저가 아닌 (부하직원이 없는) 사원들의 연봉합계는 얼마인가 => 다시

SELECT SUM(sal) FROM emp

WHERE empno NOT IN (SELECT mgr FROM emp WHERE mgr IS NOT NULL);

 

 

9. 매니저이름, 부하직원이름, 부서명 을 보이시오 (매니저이름으로 정렬)

SELECT m.ename, e.ename, dept.dname FROM emp e, emp m, dept

WHERE e.mgr=m.empno AND dept.deptno=m.deptno ORDER BY m.ename;

 

 

10. SCOTT 의 매니저는 연봉이 얼마인가

SELECT m.sal FROM emp e, emp m

 WHERE e.mgr=m.empno AND e.ename='SCOTT';

 

11. Asia 지역에 있는 국가의 국가명, 도시명을 보이시오

SELECT country.name, city.name FROM country, city WHERE country.continent='Asia' AND country.code=city.counrtycode;

 

12. South Korea 에 있는 도시명, 도시 인구수(population)를 보이시오

SELECT city.name, city.population FROM country, ciry WHERE country.code=city.countrycode AND country.name = 'SOUNT KOREA';

 

13. South Korea 에 있는 도시중 인구수가 100만 이상인 도시의 도시명, 도시 인구 수(population)를 보이시오

SELECT city.name, city.population FROM city, counrty WHERE

city.popluation>=1000000 AND city.counrtycode=country.code AND country.name='south korea';

 

14. GNP 가200 미만인 국가의 국가명, 도시명, 도시 인구수를 보이시오

SELECT country.name, city.name, city.popluation FROM country, city 

WHERE country.code=city.countrycode AND country.gnp < 200;

 

15. Laos 에 있는 도시수를 보이시오

SELECT COUNT(city.name) FROM country, city WHERE country.code=city.countrycode AND country.name='laos';

 

16. 국가명, 그 국가의 도시의 수를 보이시오 => 다시

SELECT country.name, COUNT(*) FROM country, city

WHERE country.code=city.countrycode

GROUP BY country.name;

 

 

17. 국가명, 그 국가 도시의 평균 인구수를 보이시오

SELECT country.name, AVG(city.popluation) FROM country, city WHERE

country.code=city.countrycode GROUP BY country.name;

 

18. 국가 인구수가 1000만명이 안되는 국가의 국가명, 도시명을 보이시오 => 다시

SELECT country.name, city.name FROM country, city

WHERE country.code=city.countrycode AND country.popluation < 10000000;

 

19. EUROPE 에 있는 국가중 국가 인구수가 1000만명이 안되는 국가의 국가명, 도시 명을 보이시오

SELECT country.name, city.name FROM country, city WHERE

country.code=city.countrycode  AND country.continent='EUROPE' AND country.population<10000000;

 

20. Asia 지역에 있는 국가중 GNP가 20000 이상이고 인구수가 3000만이상인 국가 의 국가명, GNP, 도시명, 도시인구수를 보이시오

SELECT country.name, city.name, city.population FROM country, city

WHERE country.code=city.countrycode AND country.continent ='Asia' AND gnpe >=20000 AND couintry.population>=30000000;

 

1. 연봉을 가장 적게 받는 사원의 이름, 연봉, 부서명을 보이시오

SELECT ename, sal, dname FROM emp, dept 

WHERE emp.deptno=dept.deptno AND sal = (SELECT MIN(sal) FROM emp);

 

2. 연봉을 평균 이상 받는 사원들의 이름, 연봉, 근무지를 보이시오

SELECT ename, sal, loc FROM emp, dept

WHERE emp.deptno=dept.dpetno AND sal >= (SELECT AVG(sal) FROM emp);

 

3. 연봉을 가장 적게 받는 사원의 매니저는 누구인가?

SELECT e.mgr FROM emp e, emp m 

WHERE e.mgr=m.empno AND e.sal = (SELECT MIN(sal) FROM emp);

 

4. 연봉을 가장 많이 받는 사원과 적게 받는 사원의 이름, 연봉을 보이시오 => 다시

SELECT ename, sal FROM emp

WHERE sal = (SELECT MIN(sal) FROM emp) OR sal=(SELECT MAX(sal) FROM emp);

 

5. 연봉을 가장 많이 받는 사원과 적게 받는 사원을 제외한 나머지 사원들의 총 연봉 합계를 보이시오 => 다시

SELECT SUM(sal) FROM emp

WHERE sal != (select max(sal) from emp) and sal != (select min(sal) from emp)

 

6. SALES 부서에 속한 사원들과 동일한 담당업무를 갖는 사원들의 이름, 담당업무를 보이시오 (단 SALES 부서에 속한 사원은 제외) => 다시

SELECT ename, job FROM emp, dept

WHERE dname <> 'SALES' (SALES에 속한 사람은 제외)

AND emp.deptno=dept.deptno

AND job IN(SELECT job FROM emp, dept WHERE emp.deptno=dept.deptno AND dname = 'SALES')

(SALES 부서에 속한 사원들이 가지는 업무 )

 

 

 

7. 연봉을 평균보다 500 이상 적게 받는 사원들의 이름, 부서명, 연봉을 보이시오

SELECT ename, dname, sal FROM emp, dept

WHERE emp.deptno=dept.deptno 

AND sal + 500 < (SELECT AVG(sal) FROM emp);

 

8. JAMES 보다 입사일이 빠른 사원들의 이름, 담당업무, 입사일을 보이시오

SELECT ename, job, hiredate FROM emp

WHERE hiredate < (SELECT hiredate FROM emp WHERE ename='JAMES');

 

9. ADAMS 보다 연봉을 많이 받는 사람은 모두 몇 명인가

SELECT COUNT(*) FROM emp

WHERE sal > (SELECT sal FROM emp WHERE ename='ADAMS');

10. GNP가 가장 높은 국가의 국가명, GNP 를 보이시오

SELECT name, gnp FROM country

WHERE gnp = (SELECT MAX(gnp) FROM country);

 

11. 인구수가 가장 적은 국가의 국가명, GNP 를 보이시오

SELECT name, gnp FROM country

WHERE popluation=(SELECT MIN(popluation) FROM country);

 

12. 인구수가 평균 이상인 국가중 GNP가 50000 이상인 국가의 이름과 GNP 를 보이 시오

SELECT name, gnp FROM country 

WHERE popluation >= (SELECT AVG(popluation) FROM country) AND gnp >= 50000

 

13. 한국(South Korea)보다 GNP 가 높은 ASIA 국가들의 이름과 GNP를 보이시오

SELECT name, gnp FROM country

WHERE gnp > (SELECT gnp FROM country WHERE name='South Korea') AND continent = 'ASIA';

 

14. 일본(Japan)보다 인구수가 많은 ASIA 국가들의 이름, 인구수를 보이시오

SELECT name, population FROM country 

WHERE population > (SELECT population FROM country WHERE name='Japan');

 

 

15. 영토면적(SurfaceArea)이 가장 작은 국가의 이름, 영토면적을 보이시오

SELECT name, surfacearea FROM country

WHERE surfacearea = (SELECT MIN(surfacearea) FROM counrty);

 

16. Canada 보다 영토 면적이 넓은 국가는 모두 몇나라인지 보이시오

SELECT COUNT(*) FROM country WHERE 

surfaceaera > (select surfaceaera from country where name='Canada');

 

1. 연봉을 적게 받는 하위 5 명의 이름, 부서명, 연봉을 보이시오

SELECT ename, dname, sal FROM emp, dept

WHERE emp.deptno=dept.deptno 

ORDER BY sal LIMIT 5;

 

2. 연봉을 평균 보다 적게 받는 사람들 중에서 연봉이 많은 순서대로 3명을 보이시오 (사원번호, 이름, 연봉)

SELECT empno, ename, sal FROM emp

WHERE sal < (SELECT AVG(sal) FROM emp) 

ORDER BY sal DESC 

LIMIT 3;

 

3. SCOTT 보다 연봉을 많이 받는 사람들 중에서 SCOTT 와 연봉이 비슷한 사람 3 명의 이름, 부서명, 연봉을 보이시오

SELECT ename, dname, sal FROM emp, dept

WHERE emp.deptno=dept.deptno AND sal>(SELECT sal FROM emp WHERE ename='SCOTT')

ORDER BY sal

LIMIT 3;

 

4. BLAKE 보다 입사일이 늦은 사람들 중에서 상위 2명을 제외하고 3명의 이름, 부서 명, 입사일자를 보이시오 (입사일자가 빠른순으로)

SELECT ename, dname, hiredate FROM emp, dept

WHERE emp.deptno=dept.deptno AND hiredate >(SELECT hiredate FROM emp WHERE ename='BLAKE')

ORDER BY hiredate

LIMIT 2, 3;

 

5. 연봉금액이 SMITH 와 FORD 사이인 사원의 이름, 연봉을 보이시오. (단 SMITH 와 FORD 는 누가 더연봉을 많이 받는지 알 수 없다) => 다시

SELECT ename, sal FROM emp

WHERE sal BETWEEN (SELECT MIN(sal) FROM emp WHERE ename='SMITH' OR ename='FORD') 

AND (SELECT MAX(sal) FROM emp WHERE ename='SMITH' OR ename='FORD') ;

 

SMITH와 FORD를 포함하지 않으려면  AND ename NOT IN('SMITH', 'FORD')

 

 

6. 소속된 사원의 연봉 총액이 많은 상위 2개의 부서의 이름과, 연봉 총액을 보이시 오

SELECT dname, SUM(sal) WHERE emp, dept

WHERE emp.deptno=dept.deptno 

GROUP BY dname

ORDER BY SUM(sal) DESC

LIMIT 2;

 

 

1. SALES 부서에 근무하는 사원들의 연봉을 월급으로 환산하여 보이되 소수점 이하 는 버리고 보이시오 (사원이름, 월급)

SELECT FLOOR(sal/12);

 

2. 사원의 이름과 사원의 근무지를 하나의 문자열로 만들어 보이시오

SELECT CONTACT(ename, loc) FROM emp, dept

WHERE emp.deptno=detp.deptno;

 

3. 담당업무가 CLERK 인 사원의 이름과 사원의 매니저 이름을 보이되 매니저 이름 은 앞 세글자만 보이시오 => 다시

SELECT e.ename, LEFT(m.ename, 3) FROM emp e, emp m 

WHERE e.job='CLERK' AND e.mgr= m.empno;

 

4. 연봉 3000 이상인 사원의 이름, 담당업무를 보이되 담당업무가 MANAGER 인 경 우는 업무명을 BOSS 로 바꾸어 보이시오 => 다시

SELECT ename, REPLACE(job, 'MANAGER', 'BOSS') FROM emp 

WHERE sal >= 3000;

 

5. 현재 날짜와 시간을 출력 하시오

SELECT NOW();

 

6. 1981년과 1982년에 입사한 사원의 이름, 입사일자를 보이시오 (YEAR 함수 이용 할 것) => 다시

SELECT ename, hiredate FROM emp

WEHRE YEAR(hiredate) IN (1981, 1982);

 

 

7. SCOTT 사원의 입사일부터 오늘까지 근무한 날수를 보이시오 => 다시

TO_DAYS =>  00년 00월 00일 부터 날짜까지의 일자수

SELECT TO_DATYS(CURDATE()) - TO_DAYS(hiredate) + 1 (입사날도 근무일이다)

FROM emp WHERE ename = 'SCOTT'; 

 

8. 2019년 7월 12일은 2019년 1월 1일을 기준으로 몇번 째 날인가 => 다시

SELECT DAYOFYEAR('2019-07-12');

 

 

9. 입사한 날의 요일이 월요일~수요일인 사원의 이름, 급여를 보이시오 => 다시

SELECT ename, sal FROM emp

WHERE WEEKDAY(hiredate) IN (0, 1, 2);

728x90
반응형

'공부 > 데이터베이스' 카테고리의 다른 글

  (0) 2021.05.15
데이터베이스 예제 4  (0) 2021.04.20
데이터베이스 예제 2  (0) 2021.04.20
데이터베이스 예제 1  (0) 2021.04.19
정리  (0) 2021.04.19
블로그 이미지

아상관없어

,
반응형

1. 모든 사원들의 이름을 알파벳 역순으로 보이시오 => 다시

SELECT ename FROM emp ORDER BY ename DESC;

 

2. 모든 담당업무명을 알파멧순으로 보이시오 => 다시

SELECT DISTINCT job FROM emp ORDER BY job;

 

3. 모든 사원의 이름과 업무 , 급여를 급여순으로 보이시오

SELECT ename, job, sal FROM emp ORDERY BY sal;

 

4. 모든 사원의 이름과 부서번호를 입사일자순으로 보이시오

SELECT ename, deptno FROM emp ORDER BY hiredate;

 

5. 모든 사원의 사원번호, 이름, 급여를 부서번호순으로 보이시오

SELECT empno, ename, sal FROM emp ORDER BY deptno;

 

6. 담당업무별 평균연봉을 보이시오

SELECT AVG(sal) FROM emp GROUP BY job;

 

7. 부서별 평균 연봉을 보이되 많은연봉 우선으로 보이시오 => 다시

SELECT deptno, SUM(sal) FROM emp GROUP BY deptno ORDER BY SUM(sal) DESC;

 

8. 각 부서별 최고 연봉을 보이시오

SELECT deptno, MAX(sal) FROM emp GROUP BY deptno;

 

9. 모든 사원의 정보담당업무에 대해 오름차순으로, 그리고 같은 업무내에서는 연봉내림차순으로 정렬하여보이시오 => 다시

SELECT * FROM emp ORDERY BY job, sal DESC;

 

10. 각 매니저별 담당사원의 인원수, 평균 연봉을 보이시오 => 다시

SELECT mgr, COUNT(*), AVG(sal) FROM emp WHERE mgr IS NOT NULL GROUP BY mgr;

 

 

11. 각 담당 업무별로 최고 연봉과 최저 연봉을 보이시오

SELECT job, MAX(sal), MIN(sal) FROM emp GROUP BY job;

 

12. 담당업무별 인원수, 평균 연봉을 보이되 업무별 인원수가 3 명 이상인 경우에 대 해서만 보이시오

=>다시

SELECT job, COUNT(*), AVG(sal) FROM emp GROUP BY job HAVING COUNT(*) >= 3;

 

13. 각 부서별 부서번호, 사원 수, 연봉합계를 보이시오

SELECT deptno, COUNT(*), SUM(sal) FROM emp GROUP BY deptno;

 

14. 각 부서별 부서번호, 사원 수, 연봉합계를 보이되 사원 수가 3 명 이상인 부서의 정보만 보이시오.

SELECT deptno, COUNT(*), SUM(sal) FROM emp GROUP BY deptno HANVING COUNT(*) >= 3;

 

15. 부서번호 , 부서별 사원 수, 연봉 합계를 보이되 급여합계가 4000~5000 사이인 경우만 보이시오 . 단, 입사일자가 1981-01-01 이전 사원은 제외하고, 연봉합계가 많 은 순으로 출력하시오 

 

SELECT deptno, COUNT(*), SUM(sal)

FROM emp

WHERE hiredate >= '1981-01-01'

GROUP BY deptno HAVING SUM(sal) BETWEEN 4000 AND 5000;

ORDER BY SUM(sal) DESC;

 

728x90
반응형

'공부 > 데이터베이스' 카테고리의 다른 글

데이터베이스 예제 4  (0) 2021.04.20
데이터베이스 예제 3  (0) 2021.04.20
데이터베이스 예제 1  (0) 2021.04.19
정리  (0) 2021.04.19
파일 사용  (0) 2021.04.14
블로그 이미지

아상관없어

,
반응형

1. BOSTON 에 있는 부서의 이름은 무엇인가

SELECT dname

FROM dept

WHERE dname='BOSTON';

 

2. 담당업무가 ANALYST 인 사원의 이름, 입사일자를 보이시오

SELECT ename, hiredate

FROM emp

WHERE job = 'ANALYST';

 

3. 입사일자가 1981년 9월 1일 이후인 사원의 이름과 입사일자를 보이시오

SELECT ename, hiredate

FROM emp

WHERE hiredate >= '1981-09-01';

 

4. 연봉이 3000에서 4000 사이인 사원의 이름, 연봉을 보이시오

SELECT ename, sal

FROM emp

WHERE sal BETWEEN 3000 AND 4000;

 

5. 사장의 이름을 보이시오 (힌트: 사장은 매니저가 없다)

SELECT ename 

FROM emp 

WHERE mgr IS NULL;

SELECT ename FROM emp WHERE job = 'president';

 

6. 담당업무가 MANAGER 가 아닌 사원들의 이름, 담당업무를 보이시오

SELECT ename, job FROM emp WHERE job <> 'MANAGER';

 

7. 담당업무가 CLERK, ANALYST, SALESMAN 인 사원들의 이름, 담당업무, 급여를 보이시오

SELECT ename, job, sal FROM emp WHERE job IN ('CLERK', 'ANALYST', 'SALESMAN');

 

8. 연봉이 3000 에서 4000 사이 이거나 담당업무가 MANAGER 인 사원의 이름, 연 봉을 보이시오

SELECT ename, sal FROM emp WHERE (sal BETWEEN 3000 AND 4000) OR (job='MANAGER'); 

 

9. 보너스를 받는 사원들의 이름과 보너스 금액을 보이시오. (보너스가 0인 경우도 받 는 것으로 간주)

SELECT ename, comm FROM emp WHERE com IS NOT NULL;

 

10. 부서번호가 20 인 사원 중에서 담당업무가 CLERK 이고 매니저의 사원번호가 7902 인 사람의 이름을 보이시오

SELECT ename FROM emp WHERE deptno=20 AND job='CLERK' and mgr=7902; 

 

1. 담당 업무가 CLERK 인 사원은 모두 몇 명인가

SELECT COUNT(*) FROM emp WHERE job='CLERK';

 

2. 담당 업무가 CLERK 인 사원의 최고연봉 금액과 최저 연봉금액, 그리고 두 금액 의 차이 금액을 보이시오

SELECT MAX(sal), MIN(sal), MAX(sal) - MIN(sal) FROM emp FROM emp WHERE job='CLERK';

 

3. 입사일이 1981년 9월 1일 이후인 사원의 평균 연봉을 보이시오

SELECT AVG(sal) FROM emp WHERE hiredate > '1981-09-01';

 

4. 매니저의 사원번호가 7698, 7639, 7782 이 아닌 사원의 이름, 담당업무를 보이시오

SELECT ename, job FROM emp WHERE mgr IN (7698, 7639, 7782);

 

5. 1982 년도 와 1983 년도에 입사한 사원의 이름, 입사일자를 보이시오

SELECT ename, hiredate FROM emp WHERE hiredate >= '82/01/01' and hiredate <= '83/12/31' ; 

 

6. 담당업무 이름에 NA 를 포함하고 있는 사원의 이름, 담당업무를 보이시오

SELECT ename, job FROM emp WHERE job LIKE '%NA%';

 

7. 보너스를 받는 사원의 이름과 보너스와 연봉을 합한 금액을 보이시오

SELECT ename, sal+comm FROM emp WHERE comm IS NOT NULL;

 

8. 모든 사원의 연봉을 10% 올려주려면 현재보다 돈이 얼마나 더 있어야 하는지 보 이시오

SELECT SUM(sal*1.1) - SUM(sal) FROM emp;

728x90
반응형

'공부 > 데이터베이스' 카테고리의 다른 글

데이터베이스 예제 3  (0) 2021.04.20
데이터베이스 예제 2  (0) 2021.04.20
정리  (0) 2021.04.19
파일 사용  (0) 2021.04.14
트랜젝션  (0) 2021.04.14
블로그 이미지

아상관없어

,

정리

공부/데이터베이스 2021. 4. 19. 22:55
반응형

-테이블 생성

CREATE TABLE 테이블 이름 {

칼럼이름1 자료형,

칼럼이름2 자료형,

.....

};

 

 

-데이터 추가

INSERT INTO 테이블이름 VALUES(데이터1, 데이터2....)

INSERT INTO 테이블이름 (칼럼이름1, 칼럼이름2.....) VALUES(데이터1, 데이터2....);

 

 

-다른 테이블의 레코드 복사

INSERT INTO 테이블이름 SELECT * FROM 복사할테이블이름;

 

-테이블의 칼럼 구조만 복사

CREATE TABLE 새테이블이름 LIKE 복사할테이블이름;

 

-특정 칼럼 선택 후 복사

INSERT INTO tb1 (name) (SELECT number FROM tb1)

 

-레코드수 제한 표시 LIMIT

SELECT 칼럼이름 FROM 테이블이름 LIMIT 표시할 레코드수;

SELECT * FROM tb LIMIT 3;

 

SELECT * FROM tb LIMIT 3 OFFSET 3

4번째 레코드부터 표시

 

 

 

 

-not equal <>

 

-LIKE

'%A%' => %는 임의의 문자열

'__A%' => -는 문자하나를 뜻함

 

-IS NULL

SELECT * FROM tb1 WHERE age IS NULL;

 

-중복 데이터 제거 DISTINCT

SELECT DISTINCT number FROM tb;

 

 

728x90
반응형

'공부 > 데이터베이스' 카테고리의 다른 글

데이터베이스 예제 2  (0) 2021.04.20
데이터베이스 예제 1  (0) 2021.04.19
파일 사용  (0) 2021.04.14
트랜젝션  (0) 2021.04.14
SQL JOIN  (0) 2021.03.30
블로그 이미지

아상관없어

,
반응형

이더리움 지갑 마이이더월렛(MEW)’ 해킹

 

- 20184월 이더리움을 보관하는 개인지갑인 마이이더월렛 해킹사건이 발생하였다.

- 해당 사건은 마이이더월렛의 DNS 서버를 해킹하여 사용자들이 해커가 만든 가짜 사이트로 접속하였다.

공격과정은 다음과 같다.

해커들은 BGP(Border Gateway Protocol) 메시지를 위조하여 DNS를 하이재킹하였다. 따라서 특정 도메인(마이이더월렛)에 연결되는 IP주소를 다른 주소(가짜 사이트)로 변경시켜 정상적인 사용자들이 마이이더월렛에 접속 요청시 가짜사이트로 연결되었다.

해커들은 ISP업체를 해킹하여 Amazon Cloud 서비스로 가는 IP 트래픽을 가로챈다.

MyEtherWallet.comAWS DNS 서버 중Route 53을 사용하고 있었으므로, 해커는 해당 IP 트래픽이 AWS에서 서비스하는 DNS서버가 아닌 가짜 DNS서버로 보내어지게 하였다.

그리고 해커들은 가짜 DNS서버를 해킹하여 피싱사이트로 연결되게 하였다.

정상적인 사용자들은 가짜 DNS 서버에서 제공하는 IP주소로 피싱사이트를 접속하였다. 정상사이트라고 생각한 사용자들은 로그인하기 위해 지갑의 개인키를 입력하여 해커는 다른 사용자들의 지갑 개인키를 획득한다. 획득한 개인키로 지갑안의 암호화폐를 훔친다.

 

해당 사고 사례는 이웃에 있는 BGP peer들이 보내는 IP prefix정보를 무조건 신뢰하는 BGP프로토콜의 취약점을 이용하였다.

AS 10297을 가진 ISPeNet을 해킹하여 AWS에 속한 IP Prefix (205.251.192.0/24
205.251.193.0/24, 205.251.195.0/24
, 205.251.197.0/24, 205.251.199.0/24)AS 10297에 속한 prefixannounce하여 eNetBGP peer에 해당 IP주소가 왔을 때, 가짜 DNS로 연결하고 피싱사이트로 연결되게 되었다.

 

1.     ISP를 해킹하여 BGP hijacking

2.     DNS서버 해킹

3.     IP 트래픽이 해킹한 DNS서버에 연결되게 함

4.     해킹 DNS서버에 연결되면, ‘MyEtherWallet.com’의 피싱 주소로 가리키게 함

5.     정상적인 사용자는 MyEtherWallet 지갑의 개인키 입력

6.     정상적인 사용자의 MyEtherWallet 지갑의 개인키 획득 후 암호화폐 탈취

 

BGP, DNS hijacking을 하여 정상적인 DNS 서버인 척 가장하였으므로 Spoofing 공격으로 분류할 수 있다. 그리고 ISP eNetAS(Autonomous System)에 속하지 않는 IP Prefix를 속하게 수정하였으므로 Tampering 공격으로도 분류할 수 있을 것이다.

 

참고 사이트)

https://m.blog.naver.com/aepkoreanet/221262570102

https://blog.cloudflare.com/bgp-leaks-and-crypto-currencies/

https://www.kentik.com/blog/aws-route-53-bgp-hijack-what-kentik-saw/

https://speakerdeck.com/stevepotayteo/defense-techniques?slide=54

https://m.etnews.com/20180425000438

https://www.facebook.com/groups/114962092511047/permalink/166401220700467/

728x90
반응형
블로그 이미지

아상관없어

,
반응형

- Software Security가 중요한 이유?

Software는 종류가 다양하고,

----------------------------------------------------------------------------------

Systems software : OS, compiler, loader

 Business software : Payroll, accounting

 Scientific and engineering software

 Computer-aided design, simulation, weather prediction, …

 Internet software:  B2C: business-to-customer (e.g., amazon.com)

 Facebook, Google Chrome, …

 PC software : Spreadsheets, word processing, games, …

 Embedded software

 Cars, microwave ovens, cable boxes, light switches,

 “smart dust”, …

 Mobile applications 

----------------------------------------------------------------------------------

컴퓨터 보안의 많은 것들은  SW로 구현이 된다.

알고리즘, access control 등 대부분이 SW로 구현되기 때문에 Software Security가 중요하다.

따라서 구현할 때 쓰는 sw가 취약하면 의미가 없으므로, SW가 취약하면 보안은 무조건 깨진다.

만약, 강력한 암호 알고리즘을 도입한다해도 구현하는 SW가 문제 있다면 그 보안은 의미가 없을 것이다.

 

따라서 SW는 빈약한 보안의 기초가 될 수 있다.

(SW가 빈약하면 보안 자체의 기초가 흔들린다.)

 

* Software 위기의 원인

- 예산 초과

- 시간 초과

- 비효율적인 SW

- 저품질의 SW

- 때때로 요구사항을 만족 못함

- 관리불가(유지보수가 힘듬 (코드가 복잡하므로))

- 원하는 결과를 내놓지 않음 or 소스코드를 넘겨주지 않음(문제 확인이 어려움)

 

이러한 문제를 해결하기 위해 Software Engineering이 나오게 되었다.

 

* Software

Software는 실행가능한 프로그램이고, 소스코드, 라이브러리, 문서(유저 요구사항, 실제 명세서, 가이드/메뉴얼 등)이다.

그 중 핵심 기능은

데이터를 처리, 전송, 저장하는것이고

정보를 생산, 관리, 드러내는 것이다.

 

 

* Bugs, Defects, Weaknesses, and Vulnerabilities

----------------------------------------------------------------------------------

Improper initialization

Side effects

Scoping

Operator precedence

Divide-by Zero

Infinite loop

Type confusion (illegal downcasts) 

Deadlock

Integer Overflow / Underflow

Memory leak

Use-after-free

Buffer overflow = Buffer overrun

Time-of-check-to-time-of-use flaw

Format string bug

---------------------------------------------------------------------------------- 

위와 같이 다양한 종류가 있다.

취약점 보단 덜 위험하지만 문제를 일으킬 수 있다.

- bug와 취약점의 차이

bug : 의도치 않은 방향으로 잘못 행동하는 프로그램 내의 결함이다.

취약점 : bug 중에서도 공격자에 의해서 악용될 수 있는 것, 공격자가 접근할 수 있어야하고 공격자가 공격할 능력이 있어야하고 시스템 내에서 결함이 있어야한다.

 

 

SW Bugs 예시)

-------------------------------------------------------------

(초기값)

typedef unsigned int uint;

int getmin(int *arr, uint len){
	int min;
    for(int i=0;i<len;i++)
    	min = (min < arr[i]) ? min : arr[i];
    return min;
 }

min에 대한 초기값이 설정되어 있지않아 정상적으로 실행되지 않을 수 있다.

inn min = 0과 같이 초기 값을 설정해주면 된다.

 

(side effects)

if(foo == 12 || (bar = 13))
	baz == 12;

bar = 13은 항상 참이다.

foo와 baz의 값이 선언되어있지 않고 비교되고 있다.

 

(범위)

int a;
void calc(int b){
	int a = b*12;
    if(b+24 == 96)
    	a = b;
}

printf("a=%d\n", a);

=> 전역변수, 지역변수 둘다  a로 선언하여 모호하다.

=> calc함수내의 a는 함수가 종료되면 없어지므로 전역변수 a의 값이 출력된다.

 

(control flow)

int x,y;

for(x=0;x<xlen;x++)
	for(y=0;y<ylen;y++);
    	pix[y*xlen + x] = x*y;
        

두번째 for문에 ;처리하여 원하는 결과가 출력되지 않는다.

 

if (isbad(cert))
	goto fail;
    
if (invalid(cert))
	goto fail;
    	goto fail;
    
    
L10 : printf("Hello, world\n");
		goto L10

goto fail;

goto fail;

을 하면 if문을 통과하고 두번째 goto fail이 항상 실행된다.

goto를 잘 못 사용하면 무한루프(L10으로 계속 이동)에 걸릴 수 있다.

 

 

(control flow - loop)

float x = 0.1;
while(x!=1.1){
	x=x+0.1;
    printf("X=%f\n", x);
}

부동 소수점은 ==으로 비교하면 안된다.

실수는 무한히 많은데 이 실수를 유한 개의 비트로 표현하기 위해서는 근삿값으로 표현해야 하기 때문이다. =>부동소수점 반올림 오차

#include <stdio.h>
#include <float.h>    // float의 머신 엡실론 값 FLT_EPSILON이 정의된 헤더 파일
#include <math.h>     // float의 절댓값을 구하는 fabsf 함수를 위한 헤더 파일

int main()
{
    float num1 = 0.0f;
    float num2 = 0.1f;

    // 0.1을 10번 더함
    for (int i = 0; i < 10; i++)
    {
        num1 = num1 + num2;
    }

    // num1: 1.000000119209290
    if (fabsf(num1 - 1.0f) <= FLT_EPSILON)    // 연산한 값과 비교할 값의 차이를 구하고 절댓값으로
                                              // 만든 뒤 FLT_EPSILON보다 작거나 같은지 판단
                                              // 오차가 머신 엡실론 이하라면 같은 값으로 봄

        printf("true\n");    // 값의 차이가 머신 엡실론보다 작거나 같으므로 true
    else
        printf("false\n");

    return 0;
}

FLT_EPSILON(머신 엡실론)을 사용해서 오차를 감안하여 실수를 비교해야한다.

어떤 실수를 가장 가까운 부동소수점 실수로 반올림하였을 때 상대 오차는 항상 머신 엡실론 이하이다.

머신 엡실론은 반올림 오차의 상한값이며 연산한 값과 비교할 값의 차이가 머신 엡실론보다 작거나 같다면 두 실수는 같은 값이라 할 수 있다.

double, long double을 사용한다면 머신 엡실론은 DBL_EPSILON, LDBL_EPSILON을 사용한다.

 

1. 연산한 값과 비교할 값의 차이를 구한다. 

(값의 차이는 math.h 헤더 파일의 fabsf 함수를 사용하여 절댓값으로 만드므로 차이가 음수여도 상관없다.)

2. FLT_EPSILON 보다 작거나 같은지 판단

3.연산한 값과 비교할 값의 차이가 머신 엡실론보다 작거나 같다면 두 실수는 같은 값이라 판단

 

 

(control flow - loop)

int k = 1
int val = 0;

while (k = 10) {
	val++;
	k++;
}

printf (“k = %d, val = %d \n”, k, val);

while(k=10)

k=10은 항상 참이므로 무한 루프가 된다.

 

 

(Null pointer 역참조)

int *ptr = NULL;

printf(“Value of ptr: %d\n”, ptr);

int *p = 0; //NULL 대입

*p = 1; //NULL 포안터 역참조, 주소 0에 접근하는 포인터생성후 값 할당 시도함


/* -------------------------------------*/
int length;
char *buff;
scanf (“%d”, &length);

buff = (char *) malloc(length+1); // always Not NULL?

strcpy(buff, “Hello World! Welcome!”);

첫번째 코드는 포인터 변수 P에 NULL을 대입하고 주소가 0인 포인터에 값을 할당하려하였다.

따라서 세그멘테이션 결함이 발생한다.

if(p==NULL){

     exit(1);

}

과 같이 NULL 포인터를 체크해주어야한다.

 

두 번째 코드는 

malloc시 시스템에 메모리가 부족하거나 메모리 할당 조건이 맞지않아 메모리 할당을 하지 못하면 null을 반환하게 된다. 따라서 buff에 null 포인터가 들어가게된다. 따라서 malloc이 null을 반환하였는지 체크하여야한다.

 

void Pointer(int *ptr) {
	*ptr = *ptr + 5;
}
main(void) {
	int num = 10;
	Pointer(&num);
	Pointer(NULL);
}

Pointer(NULL)

null을 인자로 넘겨주면 Pointer함수에서 null에 값을 대입하려하여 null 포인터 역참조 에러가 발생한다.

 

(연산자 우선순위)

node *find(node **curr, val){
	while(*curr != NULL)
    	if(*curr->val == val) return *curr;
        else
        	*curr = *curr->next;
}

(*curr)->val로 하여야한다.

 

#include<stdio.h>

void main(){
        int x,a,b,c,d,e,f;

        a=7;b=6;c=5;d=4;e=3;f=2;

        x = a&b+c*d&&e^f==7;

        printf("X = %d\n", x);

}

x = 1

연산자 우선순위는

(*) -> (+) -> (==) -> (&) -> (^) -> (&&) 

이다.

따라서

(a&(b+(c*d)))&&(e^(f==7))가 된다.

(a&(b+(c*d))) => 7&(6+(5*4)) =  20&7 (10100 & 00111) => 100(2) = 4

(e^(f==7)) => 3^(2==7) => 11 xor 00 = 11(2) => 3

3&&4는 참이므로 1이된다 (3과 4는 참이므로)

따라서 x에는 1이 들어가게된다.

 

(Integer Security)

char cresult, c1, c2, c3;
c1 = 100; c2 = 90; c3= -120
cresult = c1 + c2 + c3;
printf(“%c, %d, %c, %d\n”, cresult, cresult, c3, c3);

changmin@ubuntu:~/Desktop/c$ ./d
F, 70, �, -120

char형은 8비트이다. 

c1+c2=190에서 char범위를 벗어난다.

임시적인 정수 승격으로 c1, c2, c3는 int형으로 변환되고 

(임시적인 정수승격 : 일반적으로 CPU가 처리하기에 가장 적합한 크기의 정수 자료형은 int형이다. 즉, int형 연산의 속도가 다른 자료형의 연산속도에 비해서 동일하거나 더 빠르다. 따라서, int보다 작은 크기의 정수형 데이터는 int형 데이터로 형 변환이 되어서 연산된다.)

계산이 끝난뒤에 값이 잘리게 된다.

따라서 c1+c2+c3는 70이된다. 

char 범위는 -128~127이므로 70이 출력된다.

 

short s1 = 32000; 
short s2 =1500;
s1 = s1 + s2;
printf("%h, %d\n", s1, s1);

changmin@ubuntu:~/Desktop/c$ ./e
%, -32036

(%h =>short 형으로 출력,  invalid conversion specifier -Wformat-invalid-specifier 라고 되는데 %h 형식을 지원하지 않는듯 하다..... short형은 %hd를 사용해야하는 것 같다.)

32000+1500은 short범위를 벗어나므로 오버플로우가 발생한다.

 

(out-of-bounds write)

배열의 크기를 벗어나거나

memcpy시 마지막 인자가 unsigned int형으로 변환되면서 언더플로우가 발생될 수 있다.

(returnChunckSize(desBuf)의 반환값이 -1일때 -1-1은 -2가 되고 unsigned int로 변환시 언더플로우발생으로 매우 큰수가 된다.)

728x90
반응형
블로그 이미지

아상관없어

,